为什么应该在类型参数之前声明生命周期参数?

3

我尝试使用一个简单的函数时遇到了这个编译器错误。实际原因是什么?在我的情况下(以下代码),在生命周期参数之前写类型参数没有任何效果。编译器不应该更明智吗?

use std::fmt::Debug;

fn random_func<T : Debug, 'a>(parameter : &'a mut T) {
    println!("{:?}", parameter);
}

fn main(){
    let mut name : String = "random".to_string();
    random_func(&mut name);
    println!("{:?}", "compiled successfully");
}

错误:

life_time_trait.rs:3:27: 3:29 error: lifetime parameters must be declared prior to type parameters
life_time_trait.rs:3 fn random_func<T : Debug, 'a>(parameter : &'a mut T) {

                                           ^~

答案最终将是“因为编译器这么说”。你还在寻找什么?这个问题似乎没有一个有用的回答。同样,你也可以问“为什么要在右括号前放左括号”或“为什么要在变量类型前放变量名”。这些类型的问题很难提供客观的回答。 - Shepmaster
1
@Shepmaster 我的观点是,编译器应该聪明到对于这个特定的问题,生命周期参数和类型参数的优先级并不重要,而且应该在不显示任何错误的情况下简单地编译程序。 - basic_bgnr
我不确定这是否会改变什么 - “为什么编译器不能聪明到替我做X”也不是一个更好的问题。我们将看看是否有人足够勇敢回答!^_^ - Shepmaster
2个回答

2

我不确定这是唯一的原因,但请记住类型参数可以有生命周期限制,但生命周期参数不能有类型限制。因此,将它们放在第一位意味着您不需要处理非前向声明。

个人认为,这个规则使事情更容易理解,也更容易实现。双赢!


鉴于类型可能取决于其他类型的限制...不是很确定? - Matthieu M.
生命周期也可以依赖于其他生命周期而有界限。 - Steve Klabnik

2
设计一门语言时,有许多更或少是任意的决策。
例如,为什么在函数参数名前允许使用mut,即使不需要也能实现相同的功能呢?为什么要求使用let声明变量,即使可以通过其他方式消除歧义?
总的来说,这归结于方便:
- 对于用户而言,也就是语法糖。 - 或者对于实现者而言。
回到上面的例子:
- mut是语法糖,避免了在函数内部使用let mut name = name;。 - let保持了LL(1)文法,使得开发替代解析器更容易(例如用于文本编辑器或IDE)。
在这种情况下,我不知道确切的原因,但这并不重要。在语法等方面,有无数这样更或少是任意的设计决策,而这样的争论很少有价值。
有人可能会认为这样会稍微方便一些,而另一个人则会回答迎合读者更为重要,并试图证明当前形式更易读……这类争论通常没有尽头,每个人都拒绝让步。
我个人欢迎这样的编译器限制(并希望有rustfmt),这样未来就不会有太多关于琐事的争论。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接