proposed by Fan Changchun @fanchangchun
经过前期讨论,我们已经确定,泛型实例化采取 “代码复制” 的方案。因为这样才能获取最佳性能,但在某些情况下可能会有代码膨胀的问题。我们会让 interface 也可以提供动态派遣的方式,来解决这个问题。
支持定义泛型全局函数,泛型成员函数,泛型类型(struct, union),泛型接口(interface)
支持泛型参数携带默认值(Rust只允许在类型定义的时候可以有默认值,泛型函数不允许)
支持泛型类型推导,特别是函数调用的时候,根据实际类型参数,推导出泛型类型实参
use std::fmt::Display;
fn f<T>(x: &T) where T : Display {
println!("{}", x);
println!("{}", std::any::type_name::<T>());
}
fn main() {
let v: i32 = 1;
// 函数调用,不需要显式指定泛型参数 f::<i32>(&v);
f(&v);
}
支持泛型约束
支持常量泛型(可用于对数组类型的统一抽象)
支持变长参数泛型(有利于写出类型安全的 printf 这种函数)
支持泛型特化(有助于性能优化)
支持泛型类型的 type alias
不支持泛型协变、逆变
考虑到我们的开发节奏,我们应该尽可能让泛型的基础能力最先开发出来,然后其他的功能就可以继续。而不需要等泛型的所有功能都完备之后再开始其他功能的开发。
从开发节奏上考虑,我提议分三个部分:
本文档描述第一阶段需要实现的特性功能。
C 标准规定的函数定义语法:
attr-spec-seq(optional) specifiers-and-qualifiers parameter-list-declarator function-body
示例:
[[maybe_unused]]
static inline int max(int a, int b)
{
return a>b?a:b;
}
泛型函数:
示例:【结论:不做 where 约束,自由一点】
// 泛型函数
[[maybe_unused]]
static inline
T max<T>(T a, T b)
{
}
struct hashmap<K, V> {
}
C 标准规定的 struct/union 定义语法:
struct attr-spec-seq(optional) name(optional) { struct-declaration-list }
union attr-spec-seq(optional) name(optional) { struct-declaration-list }
enum 类型定义不支持泛型。
泛型类型定义在 name 的后面加上 type-parameter-list 。示例:
// 泛型类型
struct MyS<T> {
T x;
int y;
};
注意:我们不允许泛型函数和泛型类型,只有单独的 ”声明“ 而没有 ”定义“。
与普通函数不同,泛型函数如果需要被多个编译单元使用,它的函数体必须写在 .h
里面。示例如下:
【语法】
struct MyS<T> {
T val;
};
T MyS<U>::f<T>(MyS<U> arg) {
}
void MyS<T>::f<U>() {
}
在泛型上下文中,新引入的泛型类型参数名,不能与外层的泛型类型参数同名。
为泛型类型的形参提供实际参数,就是泛型的实例化。语法为:
示例:
int main() {
(void)(*g)(int) = f<char>;
struct MyS<int> x; // 泛型类型实例化
x.g<char>(); // 泛型函数实例化
f<void *>(NULL); // 泛型函数实例化
return 0;
}
extern struct MyS<int>; // 声明外部有这个类型。
//
【遗留】:支持强制实例化某个版本,支持 extern 某个实例化版本的类型。
规则:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。