在Scala中使用符号的实际例子?

Scala具有符号 – 以单引号开始的名称,并且是一种string常量。

我知道Ruby的符号(它们以冒号开头)。 在Ruby中,它们用于一些元编程任务,比如为成员variables生成getter和setter(例如attr_reader :name来为name生成一个getter)。

我还没有看到很多使用Scala代码的符号。 Scala中符号的实际用法是什么?

符号是否真的适合Scala?

在Lisp的美妙之地,代码被表示为表示自己(string,数字等)的字面对象的嵌套列表,以及用作类,函数和variables之类的标识符的符号。 由于Lisp代码的结构非常简单,Lisp允许程序员在编译时和运行时对其进行操作。 显然,这样做时,程序员将不可避免地遇到符号作为数据对象。

所以在任何情况下,符号都是(而且必须是)Lisp中的对象,所以为什么不把它们用作散列表键或枚举呢? 这是自然的做事方式,它保持简单的语言,因为你不必定义一个特殊的枚举types。

总而言之,符号自然是用于代码操作,枚举和键控。 但是Java用户默认情况下(不是传统的Lisp所使用的)哈希键之间的等价关系,所以他们只能使用string作为键。 枚举types在Scala中分别定义。 最后,语言根本不支持代码作为数据。

所以不,我的印象是,符号不属于斯卡拉语言。 这就是说,我要关注这个问题的答复。 他们仍然可以在Scala中真实地使用符号,这是我现在无法想象的。

附录:根据Lisp方言,Lisp符号也可以是命名空间限定的,这当然是操纵代码时非常有用的特性,而string则不具有。

在networking上search一下,与Strings相比,Scala(像Scala这样的语言)中的符号(符号文字)的感觉似乎是一个语义问题,因此甚至有可能是编译器的意识。

“string”是一个数据types,由一系列字符组成。 你可以在string上操作,然后操纵它们。 string在语义上可以是任何文本数据,从文件名到要显示在屏幕上的消息,CSV文件中的一行或其他内容。

对于编译器 – 因此IDEstring是数据typesstring的值,像数字(数字序列)是数据types的值:整数。 在程序层面上,“foo”和“bar”没有区别。

OTOH符号是标识符,即在语义上标识程序中的项目。 在这个问题上,他们就像类名,方法名或者属性名一样。 但是,尽pipe一个类名标识了类 – 即声明类的结构和行为的属性集合,方法名称标识了方法 – 参数和语句 – ,但是符号名称标识了符号 – 本身 – 除此之外 – 。

所以编译器可以明确地区分符号'foo'和'bar',就像他区分Foo和Bar类一样。 作为编译器符号表的一部分,您可以在IDE中应用相同的机制,例如像search类Foo的用法一样search“foo”(即对此符号的引用)的用法。

相比之下,search一个string“富”将需要不同的方法,如全文扫描。 它遵循与在程序代码中search所有出现的4711相同的语义。

这就是我的理解,如果我错了,有人可能会纠正我。

根据斯卡拉书,符号是interned:“ 如果你写两次相同的符号,这两个expression式将引用完全相同的Symbol对象。

相比之下,如果String以字面的forms出现(至less在Java语言中,对于Scala并不完全确定),那么它们只能被实现。 所以我想如果你做了很多的String的序列化,然后把它放到集合中,你可以使用符号来代替,并保存一些内存。

但我同意skaffman,我并不完全相信他们的使用。

(在Ruby中, Symbol是除了元编程的例子之外,经常用作Hash es中的键,在Ruby中这是很有用的,因为在那里, String是永远不会被执行的:每个String分配新的内存。正如我所提到的那样,如果将它与大量的(de)序列化结合起来,那么Java的String也不会被拦截。

我想斯卡拉join他们,因为function语言使用它们。

但是,他们忘记了通过符号来增加引用标识符的能力,这是它们存在的核心。 在Scala 2.8中有一个实验性的特性给出了一些。 我将全面引用API文档的相关部分:


 @experimental object Invocation extends AnyRef 

reflection调用的更方便的语法。 用法示例:

  class Obj { private def foo(x: Int, y: String): Long = x + y.length } 

您可以通过以下两种方式之一反思:

  import scala.reflect.Invocation._ (new Obj) o 'foo(5, "abc") // The 'o' method returns Any val x: Long = (new Obj) oo 'foo(5, "abc") // The 'oo' method casts to expected type. 

如果你调用oo方法,并且不给types推理器足够的帮助,它很可能会推断Nothing ,这将导致ClassCastException

作者Paul Phillips

我相信符号之间的比较更快。 如果你使用的是Erlang,那么在传递消息的时候,符号会被使用一吨,而且你想要一些便宜,快速的东西,在ACROSS机器的边界上效果很好。 我不确定哪个国家的远程参与者在Scala,IIRC,他们是相当狡猾的,但是将来当他们到位的时候,象Erlang那样的符号可能非常有用。 还有案例类,其中一些好处并不明显,那么再次,符号仍然更便宜。

我想你会使用它们,当你想引用的东西不是代码中的现有标识符的名称。 Scala书提供了一个引用数据库列的例子 – 它不是一个任意的string,它实际上是一个事物的名字。

虽然有点脆弱,但我并不完全相信。

我可以命名一个符号在Scala中真正使用的例子。 Play 2.2使用匿名来访问数据库。 这里有一个简单的添加实体方法的代码示例:

 def add(e:Entity): Option[Long] = { DB.withConnection {implicit conn => SQL("insert into ENTITY(name, description) values({name}, {description})").on('name -> e.name, 'description -> e.description).executeInsert() } } 

所以你可以在.on(bla bla bla)中看到符号的用法。使用String文字而不是符号也是绝对有效的,而且有些人是这样做的,但是在规范的源代码中,相应的方法签名确实使用了Symbol paremetertypes。

如前所述,符号从其他(更多)function语言中结转。 其他人没有提到的是,它们不仅填充了符号的作用,而且也是最接近的关键字(相当于性能优势)。 在我看来,他们更有用的关键字,这意味着明确的标识符。

下面我将包含来自Clojure关键词和符号文档的法庭描述。

符号

符号是通常用于引用其他内容的标识符。 它们可以用程序forms来引用函数参数,允许绑定,类名和全局variables。 他们有名字和可选的名字空间,两者都是string。 符号可以有元数据(见元)。

关键词

关键字是评估自己的符号标识符。 他们提供非常快速的平等testing。 像符号一样,它们有名字和可选的名字空间,两者都是string。 前导“:”不是名称空间或名称的一部分。

在某些语言中,Scala符号不如符号强大。 因此,它们也没有那么有用。 不过,我不明白他们为什么不能提供与关键字相同的元编程和性能优势。 至less,他们可以使你的代码更容易阅读。