更新,对于数组的部分,直接是错的:
你没有办法制定一个不可变的数组指针,而它指向的数组的元素却是可变的。
fn main() { let shit = &mut [1i32]; // 王垠的代码第一个错误是,他的变量绑定的是数组类型,这里按照他的原话绑定一个指向数组的指针。 shit[0] = 7; println!("{}", shit[0]); // 会输出 7。 shit = &mut [2333] // 编译错误,注释这一行来通过编译。注意看错误信息。 }
这段代码和他描述的行为完全一致。我想不出有能辩解的点,这是最基础的部分。
Rust 中有底层 const 和顶层 const 的区别,也就是说变量是一个 &mut 和变量本身 mut 是不一样的。
这种低级错误是态度问题了,我相信他没用 Rust 写过超过两千、不、一千、不、五百行代码。却要试图评论。让我感觉自己在知乎评价他的文章很蠢。
---很抱歉把更新的内容放到上面,因为分割线下的内容不用看了的分割线---
很难想象王垠会觉得 () 是不重要的类型,这个类型可能是所有类型中最重要的了。
也就是说,theSky = "blue" 的所有功能应该只是“赋值”这种“副作用”,副作用不应该具有“值”。即使你牵强附会说它有一个值,它的“值”也应该是 void(随之这个void 会被类型检查所拒绝,因为它不是 if 所期望的 bool)。
首先 () 是有用的,可以看作一个类型占位符,比如说对于用于错误处理的类型 Result<T, E> ,成功返回结果 T 失败返回错误类型 E,但是对有些副作用操作,成功以后没有返回值,就可以用 Result<(), E>。
更重要的是:
if (...) { a = b } // if 语句块整体为 () ,else 默认为 (),整体类型保持一致,if 有返回类型就可以出现在任何能放表达式的地方。 match x { Foo(x) => y = x, _ => println!("nothing"), } // 同理
副作用有空值,是统一有返回值和无返回值的基础,也是能将表达式视为函数来嵌套的基础。
其次变量被赋值了 () 以后(代表变量的类型也为 (),实际上会被优化掉 ),任意有地方试图把它当作别的类型的变量来访问,都会有一个编译时类型错误。