多级隐式转换,为什么 int to double 自动工作? [英] implicit conversion over multiple levels, why does int to double automatically work?

查看:32
本文介绍了多级隐式转换,为什么 int to double 自动工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直认为在 Scala 中不可能在多个级别上进行隐式转换(除非您定义视图边界:http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bounds.html)

I was always figuring implicit conversions over multiple levels is not possible in scala (unless you define view bounds: http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bounds.html)

但是好像是类型系统有缺陷或者不一致.以下示例(改编自 如何在 Scala 中链接隐式?)

But it seems that there is a flaw in the type system or an inconsistency. Following an example (adapted from How can I chain implicits in Scala?)

class A(val n: Double){
  def total = n + 10
}

object T1{
  implicit def toA(n: Double): A = new A(n)
  val i : Int = 5
  println(i.total) //Why does this work?
  println(5.2.total)
}

我真的不明白为什么从 Int -> Double -> A 的隐式转换有效.有人可以解释原因吗?谢谢

I do not really understand why the implicit conversion from Int -> Double -> A works. Can someone please explain the reasons? Thanks

推荐答案

它通过一种不同的机制发生,对于数字类型来说是独一无二的,称为数字加宽.

It happens via a different mechanism, unique to the numeric types, called numeric widening.

SLS 6.26.1 价值转换 说:

以下五种隐式转换可以应用于具有某种值类型 T 并且使用某种预期类型 pt<进行类型检查的表达式 e/em>.

The following five implicit conversions can be applied to an expression e which has some value type T and which is type-checked with some expected type pt.

静态重载解析

类型实例化

数字加宽

数字字面缩小

价值丢弃

查看申请

动态成员选择

(好吧,超过五个……不知道为什么:)

(Okay, that's more than five....not sure why :)

感兴趣的是数字加宽:

如果 e 有一个原始数字类型 弱符合预期类型,使用数字转换方法toShorttoChar、toInttoLongtoFloattoDouble 定义了 此处.

If e has a primitive number type which weakly conforms to the expected type, it is widened to the expected type using one of the numeric conversion methods toShort, toChar, toInt, toLong, toFloat, toDouble defined here.

3.5.16 弱一致性

在某些情况下,Scala 使用更通用的一致性关系.类型 S 弱符合类型 T,写作 S<:wT,如果 S<:T 或 S 和 T 都是原始数字类型,并且 S 按以下顺序排在 T 之前.

In some situations Scala uses a more general conformance relation. A type S weakly conforms to a type T, written S<:wT, if S<:T or both S and T are primitive number types and S precedes T in the following ordering.

Byte  <:w Short
Short <:w Int
Char  <:w Int
Int   <:w Long
Long  <:w Float
Float <:w Double

所以 println(i.total) 变成了 println(i.total.toFloat) 因为 Int <:w <: Long <: Float.

So println(i.total) becomes println(i.total.toFloat) because Int <:w <: Long <: Float.

Java(以及 C# 和许多其他语言)具有数字加宽功能,Scala 决定保留它.

Java (and C# and many other languages) have numeric widening, and Scala decided to keep it.

请注意,反过来是行不通的:Float 不能通过这种方式隐式转换为 Int,因为幅度可能会丢失;这不是扩大".

Note that the reverse does not work: a Float cannot be implicitly converted to Int via this way, since magnitude could be lost; it's not a "widening".

您可以添加 -Ywarn-numeric-widen 并在发生这种情况时收到警告.

You can add -Ywarn-numeric-widen and get a warning when this happens.

这篇关于多级隐式转换,为什么 int to double 自动工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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