Rust 什么';在公共函数中使用私有类型的最佳方式是什么?

Rust 什么';在公共函数中使用私有类型的最佳方式是什么?,rust,private,public,Rust,Private,Public,我有以下代码: 使用std::convert:{From,Into}; #[派生(PartialEq,Debug)] 枚举FindBy,用于FindBy Self{ Self::U(v) } } 由Self查找的impl{ Self::S(v) } } impl TileSet{ pub fn find>>(&'s self,key:K)->&'r Tile{ 匹配key.into(){ FindBy::S(k)=>&self.list.get(k).unwrap(), FindBy::ST(k

我有以下代码:

使用std::convert:{From,Into};
#[派生(PartialEq,Debug)]
枚举FindBy,用于FindBy Self{
Self::U(v)
}
}
由Self查找的impl{
Self::S(v)
}
}
impl TileSet{
pub fn find>>(&'s self,key:K)->&'r Tile{
匹配key.into(){
FindBy::S(k)=>&self.list.get(k).unwrap(),
FindBy::ST(k)=>&self.list.get(k).unwrap(),
FindBy::U(k)=>match&self.list.get_索引(*k){
一些((uv,v))=>&v,
_=>待办事项!(),
},
}
}
}
导致此警告的原因:

警告:私有类型`prelude::sys::element::tile\u set::FindBy&'r tile{
47 | |将键匹配到(){
48 | | FindBy::S(k)=>&self.list.get(k.unwrap(),
49 | | FindBy::ST(k)=>&self.list.get(k.unwrap(),
...  |
54 | |         }
55 | |     }
| |_____^
|
=警告:编译器以前已接受此选项,但正在逐步取消;这将成为未来版本中的一个硬错误!
=注:有关更多信息,请参阅第34537期
FindBy
从未公开过-它的目的是提供一个白名单,允许一个参数采用多种类型,但类型本身绝不打算用于外部,仅用于内部,但它抱怨公共接口中存在私有类型

请允许我澄清,
FindBy
永远不会在其内部的模块/文件之外使用,但是它是函数签名的一部分,并且函数是
公共的

我不想公开
FindBy
,而且从来没有公开过,但因为它在公共函数中用于为参数提供类型白名单,所以Rust抱怨


解决此问题的最佳方法是什么?

将参数限制为几种可能类型之一的常见解决方案是使用

因此,对于您的
find
函数,您可以使用trait
FindBy
(如链接中所述密封,因此没有其他人可以实现)来封装每种类型的不同逻辑,而不是使用
enum FindBy
并分派其变体,大致如下(未测试):

impl TileSet{
发布fn查找(&self,键:K)->&Tile{
键。在(自我)中查找
}
}
发布特征查找人:private::Sealed{
fn在和的瓷砖中找到;
}
为&“usize”使用impl FindBy{
fn在(self,tileset:&ts tileset)->&ts Tile中查找{
匹配&tileset.list.get\u索引(*self){
一些((uv,v))=>&v,
_=>待办事项!(),
}
}
}
//为&“str{…}的impl FindBy
//为&''字符串{…}的impl FindBy
国防部私人{
pub属性{}
为&“usize{}执行密封
impl为&“str{}密封
为&''字符串{}的impl密封
}

如果您希望它只能通过
TileSet::find
使用,还可以将方法(我在中称之为
find_)移动到private trait。此外,您可能需要考虑实现<代码> uSuth的特性,而不是<代码>和'uuSigs(但也许您有一个很好的理由来引用)。您提供的代码不会生成您询问的错误。如果您试图重现您的错误(如果可能的话),或者在全新的货运项目中,那么我们将更容易帮助您,然后您的问题将包括附加信息。您可以使用以下方法减少在此处发布的原始代码。谢谢看起来你的问题可能会由或的答案来回答。如果没有,请回答您的问题以解释差异。否则,我们可以将这个问题标记为已回答。这些问题似乎是关于返回私有类型的,这不是我要问的,因为我没有返回私有类型;正如我所说的“但类型本身绝不打算用于外部,仅用于内部”。“返回”与“接受”在这里并不相关,关键是类型在签名中。你是否尝试过这些解决方案,看看它们是否有效?那么你同意这个问题是的重复?因此,将类型公开,并将
impl-TileSet
更改为
impl-TileSet:private::Sealed
?Shepmaster:我认为这个问题的不同程度足以有自己的答案,因为OP中的私有枚举实际上只允许
find
将多个不同的公共类型作为其参数。你在这个问题上的回答没有提到封闭的特征,因为它们很可能不适用于那里;Thermatix:没有,但是我会补充我的答案来澄清。@jplatte,谢谢你是唯一一个有足够理性的人来真正阅读这个问题。