为什么在Julia中不可变性是设置在类型上而不是变量上?

4
在Julia中,为什么不可变性是整体类型的“属性”(在Julia的意义上,更类似于其他语言中的结构体或类),而不是变量?
例如,在Rust(以及我认为大多数支持不可变性的语言中),是否不可变是针对特定变量设置的,而不是整体类型 - 即没有单独的Vector vs ImmutableVector结构。要创建不可变向量,我使用let v = Vec :: new()。要创建可变的,我使用let mut v = Vec :: new()。因此,mut是可以应用于任何结构的关键字。
这似乎更方便,因为您可以使任何内容都是不可变的,并且变量默认情况下是不可变的(这正是Julia人员希望人们尽可能做到的[1])。 Julia方法有实用性或性能优势吗?
1:https://github.com/JuliaLang/julia/issues/13#issuecomment-11007166
2个回答

5

不可变性是针对特定变量而不是整体类型设置的

我认为在类型和值的意义上有些混淆。

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

let v = Vec::new().
let mut v = Vec::new()

所以这些看起来都是同一类型 "Vec",但第二个却不可变。你通过一个新的关键字 "mut" 给它打上了一个额外的不可变属性。

你可以将这个属性想象成类型的一部分,例如:

let v = Vec<Pure>::new().
let v = Vec<Mutable>::new().

使用类型参数来传递可变/不可变标记。一个好处是不需要额外的关键词,但它需要一种支持高阶类型的类型系统。
"mut"关键词实际上是向编译器传达特定属性的另一种方式--它添加了"type"信息。如果类型系统足够表达性,该信息也可以直接在类型语法中传递。无论哪种方式,编译器都知道该属性并可以对其进行优化。
因此,总之,即使可变性/效果不是具体类型语法的一部分,它们仍然在“类型”逻辑上被视为编译器所看到的一部分。像'mut'关键字这样的技巧是用于用这些信息注释类型的方式,类似于其他语言中类型的参数行为。

let mut v = Vec::new() 中,mut 使得 v 可变,因为在 Rust 中不可变性是默认的。 - user4235730
好的。回到 Rust,可变性/不可变性 类型的一部分,但你可以针对每个变量设置它。它不是针对给定类型的所有实例设置的,就像 Julia 一样。这种差异比语法更深入。我会尝试编辑问题以使其更具体。 - ysimonson
2
我认为这个答案的重点是可变性与不可变性(而不是绑定的常量性)是类型的特征,而不是变量的特征。Rust 在这里所做的是隐式地为您声明的每种类型创建 两种 类型 - 可变版本和不可变版本。 - StefanKarpinski

1

我认为这主要是一个语义上的区别。虽然比Rust语法略微不方便,但如果你真的想要,你可以在Julia中使用abstract类型做同样的事情:

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

现在使用适当的 Mut/Immut 类型声明您的变量,但对于需要类型声明的任何函数参数,请使用 MyType

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接