Rust 在线摸索(十):泛型之实现
回顾
感谢 上篇 评论区指出,struct 一节 的例程未吃透。如这个 unit struct:
// Instantiate a unit struct
let 某单元 = 单元;
实例化不需要括号。如果加了括号则报错,比较意外:
error[E0618]: expected function, found struct `单元`
--> src/main.rs:64:15
|
11 | struct 单元;
| ----------- struct `单元` defined here
...
64 | let 某单元 = 单元();
| ^^^^--
| |
| call expression requires function
|
help: `单元` is a unit struct, and does not take parentheses to be constructed
|
64 - let 某单元 = 单元();
64 + let 某单元 = 单元;
|
For more information about this error, try `rustc --explain E0618`.
经回复进一步指点,三种struct实例化的语法与定义语法有一一对应关系(unit 无括号,tuple 用小括号,具名字段的用大括号)。好奇为何不直接用一种语法?在可以从定义很明显看出区别的情况下,还用小括号和大括号作语法上的区分,是否有另外的设计考虑呢?小括号更多是用在函数参数,大括号多用在代码块,但这和具名与否有何关联呢?
也试了一下这样用错括号:
struct 对子 {
x: i32,
y: f32,
}
let x = 1;
let y = 0.1;
let 某对子 = 对子(x, y);
报错里找到了命名相近的结构:
error[E0423]: expected function, found struct `对子`
--> src/main.rs:75:15
|
14 | struct 对(i32, f32);
| -------------------- similarly named tuple struct `对` defined here
15 |
16 | / struct 对子 {
17 | | x: i32,
18 | | y: f32,
19 | | }
| |_- `对子` defined here
...
75 | let 某对子 = 对子(x, y);
| ^^^^^^^^^^
|
help: use struct literal syntax instead
|
75 | let 某对子 = 对子 { x: val, y: val };
| ~~~~~~~~~~~~~~~~~~~~~~~
help: a tuple struct with a similar name exists
|
75 | let 某对子 = 对(x, y);
| ~~
For more information about this error, try `rustc --explain E0423`.
修正后的对照如下。在可读性方面,除了从初始化语句可看出该 struct 的细分类型之外,不知有何其他好处?
struct 对(i32, f32);
struct 对子 {
x: i32,
y: f32,
}
let 某对 = 对(x, y);
let 某对子 = 对子{x, y};
泛型之实现
继续吧。
空定义
struct 甲; // Concrete type `甲`
struct 泛型类<类>(类); // Generic type `泛型类`
// impl of 泛型类 where we explicitly specify type parameters:
impl 泛型类<f32> {} // Specify `f32`
impl 泛型类<甲> {} // Specify `甲` as defined above
// `<类>` Must precede the type to remain generic
impl<某类> 泛型类<某类> {}
类
只在 泛型类
定义时有效(scope),如果在 impl<某类> 泛型类<某类> {}
用 类
就报错:
error[E0412]: cannot find type `类` in this scope
--> src/lib.rs:9:14
|
9 | impl<某类> 泛型类<类> {}
| ---- ^^
| |
| similarly named type parameter `某类` defined here
|
help: a type parameter with a similar name exists
|
9 | impl<某类> 泛型类<某类> {}
| ~~~~
help: you might be missing a type parameter
|
9 | impl<某类, 类> 泛型类<类> {}
| ++++
For more information about this error, try `rustc --explain E0412`.
看到第二个建议,想起了 昨天看到 的报错 unused type parameter
,试了下果然报错:
error[E0207]: the type parameter `某类` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:9:6
|
9 | impl<某类, 类> 泛型类<类> {}
| ^^^^ unconstrained type parameter
For more information about this error, try `rustc --explain E0207`.
这种建议的代码本身有错的情况对新手来说影响会更大。
非空定义
3i32
这种表达挺扎眼,去掉 i32
输出相同。如果用char的话,报错如下:
error: invalid suffix `char` for number literal
--> src/main.rs:25:23
|
25 | let y = 泛型值类 { 泛型值: 3char };
| ^^^^^ invalid suffix `char`
|
= help: the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)
至于 &,似乎那段目标代码里没有,其在类型的作用暂不深究。
中文化后代码:
struct 值类 {
值: f64,
}
struct 泛型值类<类> {
泛型值: 类,
}
// impl of 值类
impl 值类 {
fn 取值(&self) -> &f64 {
&self.值
}
}
// impl of 泛型值类 for a generic type `某类`
impl<某类> 泛型值类<某类> {
fn 取值(&self) -> &某类 {
&self.泛型值
}
}
fn main() {
let x = 值类 { 值: 3.0 };
let y = 泛型值类 { 泛型值: 3i32 };
println!("{}, {}", x.取值(), y.取值());
}