在Julia中,符号与Lisp、Scheme或Ruby中的符号相同。然而,对于那些相关问题的答案,我认为
并不是真正令人满意。如果你阅读那些答案,似乎符号与字符串不同的原因是字符串是可变的,而符号是不可变的,并且符号也是“内部化”的——不管那意味着什么。在Ruby和Lisp中,字符串确实是可变的,但在Julia中却不是这样,而这种差异实际上是一个误导。符号被内部化——即由语言实现进行哈希处理以进行快速的相等比较——也是一个无关紧要的实现细节。你可以有一个不内部化符号的实现,而语言本身不会有任何变化。
所以,什么是符号呢?答案在于Julia和Lisp有一个共同点 - 就是能够将语言的代码表示为语言本身的数据结构。有些人称之为
"同像性"(
维基百科),但其他人似乎认为这一点还不足以使一种语言成为同像性的。但术语并不重要。关键是,当一种语言能够表示自己的代码时,它需要一种方式来表示赋值、函数调用、可以写成字面值的东西等等。它还需要一种方式来表示自己的变量。也就是说,你需要一种方式来将这个左边的
foo
表示为数据:
foo == "foo"
现在我们来到了问题的核心:符号和字符串之间的区别在于比较中左侧的
foo
和右侧的
"foo"
。在左侧,
foo
是一个标识符,它在当前作用域中评估绑定到变量
foo
的值。在右侧,
"foo"
是一个字符串字面量,它评估为字符串值"foo"。在Lisp和Julia中,符号是表示变量的数据方式。字符串代表它自己。通过将
eval
应用于它们,您可以看到它们之间的区别:
julia> eval(:foo)
ERROR: foo not defined
julia> foo = "hello"
"hello"
julia> eval(:foo)
"hello"
julia> eval("foo")
"foo"
符号
:foo
的评估取决于变量
foo
是否绑定到某个值,而
"foo"
始终只评估为"foo"。如果您想在Julia中构建使用变量的表达式,那么您正在使用符号(无论您是否知道)。例如:
julia> ex = :(foo = "bar")
:(foo = "bar")
julia> dump(ex)
Expr
head: Symbol =
args: Array{Any}((2,))
1: Symbol foo
2: String "bar"
typ: Any
那些被倒出来的东西显示的其中一件事是,在引用代码
foo = "bar"
后,表达式对象中有一个
:foo
符号对象。这里还有另一个例子,使用存储在变量
sym
中的符号
:foo
构建一个表达式。
julia> sym = :foo
:foo
julia> eval(sym)
"hello"
julia> ex = :($sym = "bar"; 1 + 2)
:(begin
foo = "bar"
1 + 2
end)
julia> eval(ex)
3
julia> foo
"bar"
如果你尝试在
sym
绑定到字符串
"foo"
时执行此操作,它将无法工作。
julia> sym = "foo"
"foo"
julia> ex = :($sym = "bar"; 1 + 2)
:(begin
"foo" = "bar"
1 + 2
end)
julia> eval(ex)
ERROR: syntax: invalid assignment location ""foo""
这很明显为什么这样做行不通——如果你试图手动分配
"foo" = "bar"
,也不会起作用。
这就是符号的本质:符号用于在元编程中表示变量。一旦你将符号作为一种数据类型,就会有诱惑将它们用于其他用途,比如哈希键。但这只是一种偶然的、机会主义的使用方式,它并非符号这种数据类型的主要目的。
请注意,我已经停止讨论Ruby一段时间了。这是因为Ruby不是同构的:Ruby不将其表达式表示为Ruby对象。因此,Ruby的符号类型有点像是一种退化的器官——一种从Lisp继承而来的遗传适应,但不再用于其原始目的。Ruby的符号已经被用于其他目的——作为哈希键,从方法表中提取方法——但在Ruby中,符号不用于表示变量。
关于为什么在DataFrames中使用符号而不是字符串,这是因为通常将列值绑定到用户提供的表达式中的变量内部。因此,列名自然应该是符号,因为符号正是您用来表示变量作为数据的方式。目前,您必须编写
df[:foo]
来访问
foo
列,但在将来,您可能可以使用
df.foo
来访问它。当这成为可能时,只有那些名称是有效标识符的列才能使用这种便捷的语法进行访问。
另请参阅:
- [Julia官方文档:元编程](https://docs.julialang.org/en/v1/manual/metaprogramming/)
- [类似Elixir和Julia的语言在什么意义上是同像的?](https://link2)