可能重复:
What are some example use cases for symbol literals in Scala?
Symbol的目的是什么?为什么它需要一些特殊的 literal 语法e。 G。 'FooSymbol
?
答案 0 :(得分:89)
符号用于您希望能够快速比较的一组封闭标识符。当你有两个String
个实例时,它们不能保证被实习[1],所以为了比较它们,你必须经常通过比较长度检查它们的内容,甚至逐个字符地检查它们是否相同。对于Symbol
个实例,比较是一个简单的eq
检查(即Java中的==
),因此它们是查找的常量时间(即O(1))。
这种结构往往更多地用于动态语言(特别是Ruby和Lisp代码往往会大量使用符号),因为在静态类型语言中,人们通常希望按类型限制项目集。 / p>
话虽如此,如果你有一个密钥/值存储区,其中存在一组受限制的密钥,使用静态类型对象将变得难以处理,Map[Symbol, Data]
式结构可能很好对你有好处。
有关String
实习Java(以及Scala)的说明:无论如何,Java String
都会被封锁;特别是字符串文字会自动实现,您可以在intern()
实例上调用String
方法来返回实习副本。但是,并非所有String
都被实现,这意味着运行时仍然必须进行全面检查,除非它们是同一个实例; interning使得比较两个相等的实习字符串更快,但不会改善比较不同字符串的运行时间。 Symbol
受益于保证被实习,因此在这种情况下,单个参考等式检查足以证明相等或不平等。
[1]实习是一个过程,当你创建一个对象时,你检查一个对象是否已经存在,并且如果它存在则使用那个对象。这意味着如果你有两个相等的对象,它们就是同一个对象(即它们的引用相等)。这样做的缺点是,查找需要使用哪个对象的成本很高,并且允许对象进行垃圾回收可能需要复杂的实现。
答案 1 :(得分:6)
Symbol
被拘禁。
目的是Symbol
比String
更有效,并且具有相同名称的Symbol
被引用到相同的Symbol
对象(因此具有相同的哈希码) )。
看一下关于Ruby符号的阅读:http://glu.ttono.us/articles/2005/08/19/understanding-ruby-symbols
您只能获取Symbol
的名称:
scala> val aSymbol = 'thisIsASymbol
aSymbol: Symbol = 'thisIsASymbol
scala> assert("thisIsASymbol" == aSymbol.name)
答案 2 :(得分:5)
它在Scala中不是很有用,因此没有广泛使用。通常,您可以使用您想要指定标识符的符号。
例如,为2.8.0计划的反射调用功能使用了语法obj o 'method(arg1, arg2)
,其中'o'是添加到Any的方法,并且添加了方法apply(Any *)(两者都带'皮条客我的图书馆')。
另一个例子可能是,如果你想创建一种更简单的方法来创建HTML文档,那么而不是使用“div”来指定你要写'div的元素。然后可以想象添加运算符到Symbol来创建用于创建元素的语法糖