但是虽然可以编译,这样书写是绕不过静态类型检查的!!!!!!
相信大家发现了上面的string类型有些特殊,不是说string是"值类型"吗?为什么他又可以用引用类型来表示呢?string使用了没有所有权的特殊的引用类型slice,slice 允许你引用集合中一段连续的元素序列,而不用引用整个集合。
let s = String::from(“hello”);
let slice = &s[0…2];
let slice = &s[…2];
对于"值类型"的string
let s = “Hello, world!”;
这里 s 的类型是 &str:它是一个指向二进制程序特定位置的 slice。这也就是为什么字符串字面值是不可变的;&str 是一个不可变引用。
悬垂引用 悬垂指针是其指向的内存可能已经被分配给其它持有者。相比之下,在 Rust 中编译器确保引用永远也不会变成悬垂状态 例如以下代码:
fn main() {
let reference_to_nothing = dangle();
}
// wrong
fn dangle() -> &String {
let s = String::from(“hello”);
&s
}
//safe
fn safe() -> String {
let s = String::from(“hello”);
s
}
因为 s 是在 dangle 函数内创建的,当 dangle 的代码执行完毕后,s 将被释放。不过我们尝试返回它的引用。这意味着这个引用会指向一个无效的 String,这可不对!Rust 不会允许我们这么做 总结两条规则
-
在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。
-
引用必须总是有效的。
到这里和JavaScript有联系的,并且基础的就分享的差不多了,隐约记得鲁迅说过,如果你对一门语言,了解了其基本的语法,能够编写对应的简单的代码来实现简单的功能,那么你就入门了。后续的包括以下部分,就先按下不表
-
Cargo : Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。类似于JS使用的npm/pnpm/yarn
-
常见集合:Hashmap(类似于js中的map),Vector(类似于js中的数组),String
-
错误处理:panic(Throw Error 完全阻塞了程序执行) Result(类似于warning 可以报错但是不影响程序的执行)
-
…
最后总结一下rust我认为最令人称道的两点
-
丰富而强大的类型系统
-
可信赖的所有权模型
Rust and WebAssembly
====================
上面讲了半天rust,他只是我们今天的猪脚之一,那么今天的猪脚还有哪位呢?没错,就是 WebAssembly。那么WebAssembly到底是什么呢?在说这个之前先康康JavaScript的是怎么进行编译的 这就不得不说到两种编译方式了
- AOT: Ahead-of-Time compilation
必须是强类型语言,编译在执行之前,编译直接生成CPU能够执行的二进制文件,执行时CPU不需要做任何编译操作,直接执行,性能最佳,比如C/C++,Rust
- JIT: Just-in-Time compilation
没有编译环节。执行时根据上下文生成二进制汇编代码,灌入CPU执行。JIT执行时,可以根据代码编译进行优化,代码运行时,不需要每次都翻译成二进制汇编代码,V8就是这样优化JavaScript性能的。
举个例子,如果使用var来声明一个变量,不使用Typescript等类型系统来限定,一个变量,在多次编译的时候得到的变量的类型可能会不一样,这就导致了每一次JavaScript在执行的时候可能都会被重新编译,这就是类型系统的重要性,不仅能减少bug的发生也可以让我们的代码跑得更快
详细的说一下这个过程也就是
-
代码文件会被下载下来。
-
然后进入Parser,Parser会把代码转化成AST(抽象语法树).
-
然后根据抽象语法树,Bytecode Compiler字节码编译器会生成引擎能够直接阅读、执行的字节码。
-
字节码进入翻译器,将字节码一行一行的翻译成效率十分高的Machine Code.
有同学可能会问:JavaScript不是可以使用Typescript进行静态类型检查吗&