代码之家  ›  专栏  ›  技术社区  ›  Elazar Leibovich

为什么scala隐式地将char转换为int?

  •  9
  • Elazar Leibovich  · 技术社区  · 15 年前

    看斯卡拉的 Predef 对象,它是自动导入的,我发现 following gem

    implicit def char2int(x : Char) : Int
    

    这导致一些低级的错误潜入我的代码(使用 _1 而不是 _2 在里面 Map[Char,Int] )。我真的不明白,为什么我要 隐含地 转换 Char Int . 拥有 烧焦 类型(它只是一个数字)是为了避免将其用作数字(反之亦然)。

    我使用scala的类型系统来避免这样的错误!

    我所说的唯一的(坏的)借口是兼容Java的可怕行为。

    更新: 目前给出的两个答案给出的主要原因是,隐式转换是为了支持 烧焦 类型。比如说 'c'+1 将生成 d . 如果这就是你想要的,你应该做的

    class Char ...
        ...
        def +(x:Int) = (this.toInt+x).toChar
        def <(x:Char) = this.toInt < x.toInt
    

    你可以根据自己的喜好添加和比较字符。事实是 烧焦 只有16位数字意味着我们需要一个新的 Word (或) Short )类型。

    2 回复  |  直到 15 年前
        1
  •  5
  •   Community Marks    7 年前

    Char Int

    • Byte
    • Long

    Predef

    def foo(c: Char) { println(c) }
    foo('a' + 2) // prints c
    

    Chars applying my own guidelines for using implicits

    隐式转换关闭,因为关闭所有转换可能会破坏破坏环境!)

    我看到的解决您问题的唯一方法是使用 Map[RichChar, Int] 或者类似的东西- RichChar 被隐式转换为 int ,因为无法链接隐式转换。 编辑 发现其实 隐式转换自 里奇查 烧焦 .

    def foo(x: Int) = x + 1
    
    import scala.runtime.RichChar
    
    val ch = 'a'
    val rch = new RichChar('a')
    
    foo(ch) // compiles fine
    // foo(rch) // does not compile
    
    def bar(ch: Char) = println(ch) 
    
    // bar(rch) // oops... does not compile
    implicit def rch2char(rch: RichChar): Char = rch.self.asInstanceOf[Char]
    
    bar(rch) // yay!
    

    编辑 :实际上,如果您对scala API有一个很好的了解, Char 是否有过载 + 采用的方法 int 争论。同样的道理 Int . 这可能与基础JVM做类似的事情有关。

    还要注意,我给出的示例与允许添加 int S to 烧焦 S!API已经允许这样做。更微妙的一点是当你添加 int 到A 烧焦 ,你得到一个 int . 隐式转换允许将此加法的结果用作 烧焦 .

    还要注意我给出的更为理论化的答案- 烧焦 是一个子集 利息 你说什么?

    -- Flaviu Cipcigan

        2
  •  0
  •   DigitalRoss    15 年前

    它可能并不完美,但要考虑另一种选择…

    这只是一个实现选择。在某一点上,许多语言确实在 char int 但是,由于它们总是需要转换函数,所以实际上不会阻塞太多, 变成一个巨大的痛苦。

    没有人真的想回到 chr(n) ord(c) 到处都是。想象一下,UTF-8处理将是多么有趣。

    一旦C出来 烧焦 确实存在 int S,它摇摆不定,即使是在更为强类型的语言中,我们也坚持使用它。

    现在,你真的想要一个胶囊吗? Char 它不会自动转换,也不会阻止您定义新类型,比如 ElazarChar ,为您自己的代码。我怀疑你会讨厌它的。