late bound】为了减少对正文内容理解的歧义,我们先统一若干术语的名词解释:
泛型项:
要么,泛型函数generic function;
要么,泛型类型generic type(比如,泛型结构体)。
泛型参数:
要么,泛型·类型·参数generic type parameter;
要么,泛型·生命周期·参数generic lifetime parameter。
泛型参数限定条件:
见下图吧,实在不容易文字描述

trait bounds;lifetime bounds。higher-ranked lifetime bounds:
for<'a>FST:Fixed Size Typemonomorphize】过程中的【泛型项】定义位置。monomorphize】之后的【泛型项】调用位置(比如,函数调用)。所以,【泛型参数】的【早/晚·绑定】是一个纯编译时概念,还是馁馁的【编译时-抽象】和零运行时(抽象)成本。
rustc单态化monomorphize】期间,就能推断出【泛型参数】具体“值”,那么该【泛型参数】就是【早·绑定】。rustc单态化monomorphize】之后,还需评估【泛型项】的调用方式,才能确定【泛型参数】具体“值”,那么该【泛型参数】就是【晚·绑定】。TurboFish调用语句显示地指定 [例程1]TurboFish调用语句显示地指定 [例程2]TurboFish语法TurboFish调用语句·展开】与【泛型参数 - 晚·绑定】有两项不同:TurboFish调用语句是在【单态化monomorphize】过程中被展开的。monomorphize】之后。此时,TurboFish调用语句的源码已经不存在了(— 之前已经被展开了)。let array = iterator.collect::<Vec<u8>>();语句会导致,在【单态化monomorphize】之后,在Iterator::collect()成员方法的定义位置多出来一个fn collect(self) -> Vec<u8>的新成员方法定义。由此可见,最终的修改项还是落在了【泛型项】定义位置的codegen代码上。TurboFish语法调用语句·等同于·【泛型参数 - 早·绑定】TurboFish调用语句的【展开】处理会回过头来对【泛型项】定义位置的代码产生影响。即,【单态化】会生成更多的代码 — 这类由编译器生成的代码被称为codegen。codegen被生成。这是一个纯“调用位置”的,由【已知项】推断【未知项】的行为。其中,fn m<T>() {}let m1 = m::<u8>; // 赋值函数指针,得先确定泛型类型参数`T`的实参值`u8`。m1(); // 经由【函数指针】调用函数就没有机会再显示地指定【泛型参数】值了。
lifetime bound出现。即,【泛型·生命周期·参数】正被另一个【泛型·生命周期·参数】所限定(比如,<'a, 'b> where 'a: 'b)。有点绕儿,看 [例程4]。于是,该【泛型函数】的这两个【泛型·生命周期·参数】(限定的·与·被限定的)皆都是【早·绑定】。fn m<'a>(name: &'a str) -> &'a str {name}let m1 = m; // 'a 的生命周期参数被直接无视了。let r = m1("test"); // 函数被调用了才知道其实参的`lifetime`是`static`
// 和其返回值的`lifetime`也是`static`
higher-ranked lifetime bounds】显示地标注待定的【泛型·生命周期·参数】fn m<'a>(name: &'a str) -> &'a str {name}// `for<'a>`语法表示`'a`生命周期参数的实参待定。let m1: for<'a> fn(&'a str) -> &'a str = m; // 函数指针写法let r = m1("test"); // 函数被调用了才知道其实参的`lifetime`是`static`
// 和其返回值的`lifetime`也是`static`// 对于不嫌麻烦的你,没准【闭包`trait`写法】也是一个选择。let m2: Box<dyn for<'a> Fn(&'a str) -> &'a str> = Box::new(m);let r = m2("test");
higher-ranked lifetime bound】 [例程5]。bound:Sized缺省trait bound。即,<T: Sized>。所以,【泛型·类型·参数】一定都是FST的。lifetime参数】而言,编译器会认为该【泛型参数】生存期 >= 【泛型项】生存期。lifetime bound限定条件的四句实用口诀<'a, 'b> where 'a: 'b则有'a >= 'bfn test<'a, 'b>(a: &'a str, b: &'b str) -> &'b str where 'a: 'b<'a, 'b> where 'a: 'b则有&'b &'a i32。而,&'a &'b i32会导致编译错误。'static最”命长“ — 它馁馁地命长于任何被显示声明的生命周期参数'a。原文作者:Rust语言中文社区;如有侵权,请联系管理员删除。