Rust中如何将&T转为&Option<T>,实现Option数组的二分查找?
解决方案
你的问题核心是&Option<&K>和&Option<K>类型不匹配,无法直接用于binary_search,且你不想给K添加额外trait约束。这里有两种无需额外trait的可行方案:
方案一:使用binary_search_by自定义比较逻辑
直接在闭包里处理Option<K>和&K的比较,无需构造Option包装的key:
fn foo(&self, key: &K) { let _index = self.keys.binary_search_by(|item| { // 按你的语义,将None视为超出范围的占位符,返回Greater让它排在有效元素之后 item.as_ref().map_or(std::cmp::Ordering::Greater, |k| k.cmp(key)) }); // snip }
这里用Option::as_ref()将&Option<K>转为Option<&K>,直接和传入的&K比较;遇到None时返回Greater,适配有效元素在前、None在后的数组排序逻辑。
方案二:使用binary_search_by_key按映射后的key查找
通过映射函数将数组元素转为Option<&K>,再和包装好的Some(key)比较:
fn foo(&self, key: &K) { let target = Some(key); let _index = self.keys.binary_search_by_key(&target, |item| item.as_ref()); // snip }
这个方案更简洁,binary_search_by_key会自动将数组中的每个Option<K>映射为Option<&K>,再和目标Option<&K>(即Some(key))按Rust默认的Option规则比较(Some始终小于None,同是Some则比较内部元素)。
这两个方案都只依赖K: Ord的原有约束,不需要强制K实现Default或Copy,也不用修改foo的参数类型。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

