英文:
Must we ditch From Trait to make code navigable
问题
We found the rust From
trait is lacking IDE (both PyCharm and vscode) support:
impl From<A> for B {
fn from(order: A) -> Self {...} // Impl
}
// order is of Type A
let order: B = order.into(); // Usage
Neither IDE is able to navigate from usage to implementation or vice versa.
If we use
let order = B::from(order);
then navigating from usage to impl is a breeze, but from impl to usage takes vscode 10 seconds on our code base.
If we ditch the From
trait altogether, i.e.
impl B {
pub(crate) fn from(order: A) -> Self {...}
}
then navigating either direction is instantaneous. Our Rust-consultants hate this, but we Rust beginners will understand and maintain the code base so much more efficiently!
Is there a best practice to get IDEs properly navigating (ctrl+left-click and "Go to reference") between From
usage and implementation.
英文:
We found the rust From
trait is lacking IDE (both PyCharm and vscode) support:
impl From<A> for B {
fn from(order: A) -> Self {...} // Impl
}
// order is of Type A
let order: B = order.into(); // Usage
Neither IDE is able to navigate from usage to implementation or vice versa.
If we use
let order = B::from(order);
then navigating from usage to impl is a breeze, but from impl to usage takes vscode 10 seconds on our code base.
If we ditch the From
trait altogether, i.e.
impl B {
pub(crate) fn from(order: A) -> Self {...}
}
then navigating either direction is instantaneous. Our Rust-consultants hate this, but we Rust beginners will understand and maintain the code base so much more efficiently!
Is there a best practice to get IDEs properly navigating (ctrl+left-click and "Go to reference") between From
usage and implementation.
答案1
得分: 0
以下是您要翻译的内容:
"Go to X"行为在使用rust-analyzer的VSCode中按我所期望的方式工作,但我可以理解由于From
/Into
的设计方式可能会令人不满。
.into()
方法并不是由From
特性提供的,而是由Into
特性提供的。之所以实现From
似乎允许.into()
工作,是因为Into
的通用实现实现了Into<U> for T where U: From<T>
。因此,几乎没有直接实现Into
的情况,而是实现了From
。
在您的IDE中,这意味着导航到.into()
几乎总是会将您引导到通用实现,这并不是非常有帮助,但这也是我所期望的。在this issue中有一些关于导航到相关From
实现的讨论,尽管目前尚未有任何结果,并且可能必须作为特殊情况处理。
但是,通过::from(_)
导航似乎完全正常:例如,在String::from("")
上执行"转到实现"将导航到From<&str> for String
实现,从那里导航到fn from(...
会显示给我所有使用该特定实现的情况。这需要一点时间,但我只在一个中等规模的代码库上进行了测试,所以如果性能对您是个问题,那么您可以提交一个问题。
尽管如此,如果您不想使用From
,那么您不需要使用它。如果您依赖于在通用上下文中使用转换,那么将需要一个From
实现,因此如果合适的话,我鼓励您提供它。但这并不意味着您必须直接在自己的代码中使用它:如果from_a()
或into_b()
可以提高清晰度,那么请添加它作为一个选项。甚至标准库也这样做(例如,查看String::into_bytes
与From<String> for Vec<u8>
)。我不建议使用内在的from
或into
方法,因为这很容易与特性方法混淆;给它一个更好的名字。
最后,请不要把所有的鸡蛋都放在一个篮子里。特别是对于初学者来说。您的IDE只是可发现性的一个来源:生成的文档以及任何额外的示例、测试和mdbooks共同组成了完整的理解。
英文:
The "Go to X" behavior works both ways as I'd expect in VSCode with rust-analyzer, but I can see how it can be unsatisfying due to how From
/Into
is designed.
The .into()
method is not provided by the From
trait, it is provided by the Into
trait. The reason that implementing From
seems to allow .into()
to work is due to Into
's generic implementation that implements Into<U> for T where U: From<T>
. And because of that behavior, almost nothing implements Into
directly and would implement From
instead.
What this means in your IDE though is that navigating to .into()
will almost always lead you to the generic implementation, which isn't very helpful but its also what I'd expect. There is some discussion in this issue that would propose navigating to the relevant From
implementation instead, though nothing has come of it yet and would have to be handled as a special case.
But navigating via ::from(_)
appears to work just fine: "Go to implementation" on String::from("")
for example leads to the From<&str> for String
implementation, and navigating from fn from(...
there shows me all uses of that particular implementation. It takes a moment but I've only tested on a medium-ish code base so if the performance is a problem for you then you can file an issue.
That all being said, you don't need to use From
if you don't want to. A From
implementation would be required if you relied on utilizing the conversion in a generic context and thus I would encourage you to provide it anyway if at all appropriate. But that doesn't mean you have to use it directly in your own code: if from_a()
or into_b()
improves clarity then by all means add that as an option as well. Even the standard library does it (see String::into_bytes
vs From<String> for Vec<u8>
for example). I wouldn't recommend an inherent from
or into
method since that would be easily confused with the trait method; give it a better name.
And as a final note, you shouldn't put all your eggs in one basket. Especially as a beginner. Your IDE is only one source of discoverability: the generated documentation and any supplemental examples, tests, and mdbooks work together to form a complete understanding.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论