Functional programming 为什么Julia中的类型(而不是变量)设置了不变性?

Functional programming 为什么Julia中的类型(而不是变量)设置了不变性?,functional-programming,immutability,julia,Functional Programming,Immutability,Julia,在Julia中,为什么不变性是整体类型的“属性”(在中,更类似于其他语言中的结构或类)而不是变量 e、 g.在Rust(我认为大多数支持不可变性的语言)中,某个内容是否不可变是在特定变量上设置的,而不是在整体类型上设置的,即没有单独的VectorvsImmutableVectorstructs。要创建一个不可变的向量,我需要让v=Vec::new()。要创建一个可变的,我需要让mut v=Vec::new()mut是一个可以应用于任何结构的关键字 这似乎更方便,因为您可以使任何内容都不可变,并且

在Julia中,为什么不变性是整体类型的“属性”(在中,更类似于其他语言中的结构或类)而不是变量

e、 g.在Rust(我认为大多数支持不可变性的语言)中,某个内容是否不可变是在特定变量上设置的,而不是在整体类型上设置的,即没有单独的
Vector
vs
ImmutableVector
structs。要创建一个不可变的向量,我需要
让v=Vec::new()
。要创建一个可变的,我需要
让mut v=Vec::new()
<因此,code>mut是一个可以应用于任何结构的关键字

这似乎更方便,因为您可以使任何内容都不可变,并且默认情况下变量是不可变的(Julia的人希望人们尽可能多地这样做[1])。Julia方法是否有实用性或性能方面的改进

1:

某些内容是否不可变取决于特定变量而不是总体类型

我认为对于我们赋予类型和值的含义,这里有一些混淆

在您的示例中,您给出了一个可变和不可变的向量:

let v = Vec::new().
let mut v = Vec::new()
因此,它们似乎具有相同的类型“Vec”,但不知何故,第二种类型是不可变的。您已经通过一个新的关键字“mut”为它添加了一个额外的不变性属性

您可以将此属性想象为类型的一部分,例如:

let v = Vec<Pure>::new().
let v = Vec<Mutable>::new().
让v=Vec::new()。
设v=Vec::new()。
使用类型参数传入可变/不可变标记。一个好处是不需要额外的关键字,但它需要一个支持高阶类型的类型系统

“mut”关键字实际上只是告诉编译器某个特定属性的另一种方式——它添加了“类型”信息。如果类型系统具有足够的表达能力,则该信息也可以直接以类型语法传递。无论哪种方式,编译器都知道该属性,并可以对其进行优化


因此,总之,即使可变性/效果不是具体类型语法的一部分,它们在逻辑上仍然是编译器所认为的“类型”的一部分。像“mut”关键字这样的技巧是用这些信息注释类型的方法,就像其他语言中类型的参数一样。

我认为这在很大程度上是语义上的区别。虽然不如Rust语法方便,但如果您真的愿意,可以在Julia中使用
abstract
类型执行相同的操作:

abstract MyType
type MyTypeMut <: MyType
    a::Int
end
immutable MyTypeImmut <: MyType
    a::Int
end
抽象MyType

let mut v=Vec::new()
中键入MyTypeMut,
mut
使
v
可变,因为Rust.Right中默认为不可变。回到Rust,可变性/不可变性是类型的一部分,但可以逐个变量进行设置。它不是为给定类型的所有实例设置的,比如Julia。这种差异比语法更深刻。我会尽量把这个问题编辑得更具体一些,我认为这个答案的要点是可变性与不可变性(与绑定的常量相反)是一个类型的特征,而不是一个变量。Rust在这里所做的是为您声明的每种类型隐式创建两种类型–可变版本和不可变版本。