Julia ---- Symbol 是什么

 

Julia中的符号(Symbols )与Lisp、Scheme或Ruby中的符号相同。然而,在我看来,这些相关问题的答案并不令人满意。如果你读了这些答案,似乎符号与字符串的区别仅是,字符串是可变的,而符号是不变的,而且符号也是临时的。字符串在Ruby和Lisp中确实是可变的,但它们在Julia中是可变的,而且可变性实际上也是一种危险。事实上在Julia中符号是被内联的——即由语言实现进行哈希运算以便进行快速的比较(也是一个不相关的实现细节)。你可使用符号编写代码,并且这和内联的语言的实现将完全相同。

首先 什么是符号(Symbols )?答案是(在Julia和Lisp中这一点是相同的)能够将自定义的语言代码表示为语言本身的数据结构。有些人称之为“同形性”(Wikipedia),但有些人并不认为单凭这一点就足以使一种语言具有同形性。术语其实并不重要,关键是,当一种语言使用符号可以表示它自己的代码时,它需要一种方法来表示诸如赋值、函数调用 、可以写成文本值的表达式 等等。它还需要一种方法来表示它自己的变量。例如,你需要一种方法以数据结构的方式来表示这个左边的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的计算结果取决于绑定到变量fo的对象(如果有,可以是赋值、函数调用 、可以写成文本值的表达式 等等),而“foo”的计算结果总是“foo”。如果你想在Julia中构造使用变量的表达式,那么你使用的就是符号,例如:

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”,它也不会起作用。也就是说sym 必须被赋值为一个 Symbols 时,才会起作用。

这是符号(Symbols)的本质:符号用于表示元编程中的变量。当然,一旦将符号作为数据类型,就很容易将它们用作其他用途,例如散列键。

至于为什么在DF中使用符号而不是字符串,这是因为在DF中,将列值绑定到用户提供的表达式中的变量是一种常见的模式。所以列名自然是符号,因为符号正是用来将变量表示为数据的。目前,您必须编写df[:foo]才能访问foo列,但将来,您可能可以使用df.foo访问。这也是有前提的,只有其名称与某个列的标识符相等时,才能用这种方便的语法访问。

 

Julia ---- Symbol 是什么Julia ---- Symbol 是什么 October-- 发布了93 篇原创文章 · 获赞 74 · 访问量 5万+ 私信 关注
上一篇:一个关于格式化字符串和栈溢出的综合应用


下一篇:线性分段插值