为什么 Scala 将 Char 隐式转换为 Int? [英] Why does Scala implicitly convert Char to Int?

查看:53
本文介绍了为什么 Scala 将 Char 隐式转换为 Int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看scala的Predef对象,是自动导入的,发现关注宝石

Looking at scala's Predef object, which is automatically imported, I found the following gem

implicit def char2int(x : Char) : Int

这导致一些低级错误潜入我的代码中(在 Map[Char,Int] 中使用了 _1 而不是 _2).我真的不明白,为什么我要隐式Char转换为Int.拥有 Char 类型(它只是一个数字)的整个想法是这样我就不会将它用作数字(反之亦然).

This has caused some sleazy bugs to sneak into my code (used _1 instead of _2 in Map[Char,Int]). I really don't get it, why would I want to implicitly convert Char to Int. The whole idea of having the Char type (which is a mere number) is so that I won't use it as a number (or vice versa).

我使用 Scala 的类型系统是为了避免出现这样的错误!

I use scala's type system in order not to have errors like that!

我想的唯一(不好的)借口是与 Java 的可怕行为兼容.

The only (bad) excuse I though about is to be compatible with Java's horrible behaviour.

更新: 到目前为止给出的两个答案给出的主要原因是进行隐式转换以支持对 Char 类型的有序操作.因此,例如 'c'+1 将生成 d.如果这是你想要的,你应该这样做

update: The main reason given by the two answers given so far, is that the implicit conversion is done to support ordered actions upon the Char type. So that for instance 'c'+1 would generate d. If that's what you want you should do

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

并且您可以根据自己的喜好添加和比较字符.Char 是唯一的 16 位数字这一事实仅意味着我们需要一个新的 Word(或 Short)类型.

and you could add and compare characters to your liking. The fact that Char is the only 16-bits number only means we need a new Word (or Short) type.

推荐答案

好吧,如果您考虑 Char 的表示方式,Char 就是无符号的 16 位字段,范围从 (0 到 2^16 - 1).这可以适应 Int(32 位有符号,范围从 -2^31 到 2^31 - 1)而不会溢出.

Well, if you think in terms of how a Char is represented, a Char is jusr an unsigned 16 bit field, with a range from (0 to 2^16 - 1). This can fit without an overflow in an Int (32 bit signed, with a range from -2^31 to 2^31 - 1).

Scala 的一些基本类型是,按照它们以位为单位的表示长度的顺序:

Some of Scala's basic types are, in order of the length of their representation in bits:

  • 字节 (8)
  • 字符 (16)
  • Int (32)
  • (64)
  • Byte (8)
  • Char (16)
  • Int (32)
  • Long (64)

所有都是有符号的,除了 Char 并且所有都可以转换为低于"它的类型,因为它们永远不会溢出/下溢(除了 ByteChar,不存在).在 预定义.

All are signed, except for Char and all are convertible to a type "below" it as they would never over/under-flow (except for Byte to Char, which doesn't exist). See all of those implicit conversions in the Predef.

这就是我认为存在隐式转换的原因 - 允许存在如下表达式:

This is the reason I believe the implicit conversions exist - to allow expressions like the following to exist:

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

另一种解释与您给出的解释一致(Char 只是一个数字...).对我来说它确实有意义 - 所有 Chars 的集合包含在所有 Int 的集合中,因此,应用我自己的隐式使用指南,转换应该是隐式的.

Another explanation is along the lines of the one you have given (a Char is just a number...). For me it does make sense - the set of all Chars is included in the set of all Ints, and therefore, applying my own guidelines for using implicits, the conversion should really be implicit.

我确实理解您的烦恼,因为我喜欢编译器发出错误信号,就像您刚才举的例子一样.如果 Scala 有办法关闭隐式转换(或关闭特定隐式转换,因为将它们全部关闭可能会造成严重破坏!)

I do understand your annoyance as I like compilers to signal errors like the one you have just gave as an example. It would be nice if Scala had a way to turn implicit conversion off (or turn specific implicit conversions off, as turning them all off would probably wreck havoc!)

我看到的唯一解决方案是使用 Map[RichChar, Int] 或类似的东西 - RichChar 被隐式转换为 Int>,因为不能链接隐式转换.编辑发现实际上没有RichCharChar的隐式转换.

The only solution I see for your problem is using Map[RichChar, Int] or something similar - RichChar is implicitly converted to an Int, as implicit conversions cannot be chained. EDIT found out that there actually is no implicit conversion from RichChar to Char.

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 做了类似的事情有关.

EDIT: Actually, if you have a good look at the Scala API, Char does have an overloaded + method which takes an Int argument. Same goes for Int. This could have to do with the fact that the underlying JVM does something similar.

另请注意,我给您的示例与允许将 Int 添加到 Char 无关!API 已经允许这样做.更微妙的一点是,当您将 Int 添加到 Char 时,您会得到一个 Int.隐式转换允许将此加法的结果用作 Char.

Also note that the example I have gave you had nothing to do with allowing adding Ints to Chars! This is already allowed by the API. The more subtle point is that when you add an Int to a Char, you get an Int. The implicit conversion is there to allow using the result of this addition as a Char.

另请注意我给出的更具理论性的答案 - CharInt 的子集!

Also note the more theoretical answer I have given - Char is a subset of Int !

-- Flaviu Cipcigan

这篇关于为什么 Scala 将 Char 隐式转换为 Int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆