Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 未对Int执行隐式转换_Scala_Typeclass_Implicit - Fatal编程技术网

Scala 未对Int执行隐式转换

Scala 未对Int执行隐式转换,scala,typeclass,implicit,Scala,Typeclass,Implicit,在Scala中,我想为基本类型生成一些别名,然后通过类型类实现转换。这对我来说很有用,也是理解类型类的一个机会。代码如下: type Index = Int val Index = Int type Integer = Int val Integer = Int type Real = Double val Real = Double // to have companion object of Double also be the companion object of Real tra

在Scala中,我想为基本类型生成一些别名,然后通过类型类实现转换。这对我来说很有用,也是理解类型类的一个机会。代码如下:

type Index = Int
val Index = Int

type Integer = Int
val Integer = Int

type Real = Double
val Real = Double // to have companion object of Double also be the companion object of Real

trait Convertible[A] {
  def toIndex(a: A): Index
  def toInteger(a: A): Integer
  def toReal(a: A): Real
}

implicit val ConvertibleIndex: Convertible[Index] = new Convertible[Index] {
  def toIndex(i: Index) = i
  def toInteger(i: Index) = i
  def toReal(i: Index) = i.toDouble
}

implicit val ConvertibleInteger: Convertible[Integer] = new Convertible[Integer] {
  def toIndex(i: Integer) = i
  def toInteger(i: Integer) = i
  def toReal(i: Integer) = i.toDouble
}

implicit val ConvertibleReal: Convertible[Real] = new Convertible[Real] {
  def toIndex(r: Real) = r.toInt
  def toInteger(r: Real) = r.toInt
  def toReal(r: Real) = r
}

implicit val ConvertibleString: Convertible[String] = new Convertible[String] {
  def toIndex(s: String) = s.toInt
  def toInteger(s: String) = s.toInt
  def toReal(s: String) = s.toDouble
}

implicit class ConvertibleSyntax[A](a: A)(implicit val c: Convertible[A]) {
  def toIndex = c.toIndex(a)
  def toInteger = c.toInteger(a)
  def toReal = c.toReal(a)
}
现在考虑一下:

val a = 3.toReal
val b = 3.0.toReal
val c = "3".toReal
a
的语句未编译,编译错误为:
方法toReal不是Int
的成员。但是,对于
b
c
语句,到
ConvertibleSyntax
的隐式转换是正确的


为什么隐式转换不适用于
Int
,而适用于
Double
String

,因为您为
索引和
整数定义了不明确的隐式(
Int


编译器应该选择哪一个?

,因为您为
索引
整数
(都是
Int
)定义了不明确的隐式


编译器应该选择哪一个?

我想您可能对Scala如何进行隐式转换有点困惑。(一个常见的错误是
隐式
有点过度使用。)

我认为您首先需要的是一个隐式转换函数,甚至是一个隐式类。以下是如何使用后一种方法实现这一点:

注意:
Int
Index
Integer
被同等对待,
Real
Double
也是如此,这在一定程度上混淆了问题,所以我将其简化为一些可行的方法。而且,
Convertible
不需要是泛型的,因为它的转换函数不需要参数。最后,您不应该为您的类型同时声明
type
val

类型索引=Int
整型=Int
类型Real=Double
性状转换{
def toIndex:索引
def toInteger:整数
真的吗
}
//隐式类不能在顶级作用域中定义,因此它们属于对象。
对象隐式{
隐式类可转换元素(i:Int)
延伸敞篷车{
覆盖def toIndex=i
覆盖def toInteger=i
覆盖def toReal=i.toDouble
}
隐式类ConvertibleDouble(d:Double)
延伸敞篷车{
覆盖def toIndex=d.toInt
覆盖def toInteger=d.toInt
覆盖def toReal=d
}
隐式类可转换字符串(s:String)
延伸敞篷车{
覆盖def toIndex=s.toInt
覆盖def toInteger=s.toInt
覆盖def toReal=s.toDouble
}
}
现在试试这个:

importimplicits_
val a=3.5升
val b=3.0.t真实值
val c=“3”toReal
这里发生了什么事?嗯,
隐式类
声明定义了用附加函数修饰唯一构造函数参数的类。如果编译器发现您正试图对一个没有该方法的类型调用一个方法,它将查看是否在范围内对一个有该方法的类型进行了隐式转换。如果是,则使用它并调用该函数;如果不是,则会出现编译器错误。(import
语句用于将类引入当前范围。)

因此,例如,当编译器看到
“3.toReal
时,它首先确定
“3”
字符串。由于此类型没有
.toReal
成员,因此它尝试查找从
字符串
到具有此成员的类型的转换。它查找接受
字符串
参数并提供
.toReal
方法的
可转换字符串
隐式类。耶!因此,编译器通过将
“3”
传递给
ConvertibleString
的构造函数来创建此类的实例,然后对结果调用
.toReal

另一方面,当
implicit
与值一起使用时,它会告诉编译器该值是未提供的相同类型的任何匹配隐式参数的默认值切勿将
implicit
与基元或公共库类型一起使用

例如:

最终案例类示例(i:Int)
//默认。
隐式val name canbeanythingatall=示例(5)
//具有隐式参数的函数。
def someFunc(隐式x:示例):单位=println(s“值为$x”)
现在,如果你这样写:

someFunc
输出将是
值为示例(5)


隐式
值和参数是一个高级主题,我现在不担心它们是如何使用的。

我想您可能对Scala如何进行隐式转换有点困惑。(一个常见的错误是
隐式
有点过度使用。)

我认为您首先需要的是一个隐式转换函数,甚至是一个隐式类。以下是如何使用后一种方法实现这一点:

注意:
Int
Index
Integer
被同等对待,
Real
Double
也是如此,这在一定程度上混淆了问题,所以我将其简化为一些可行的方法。而且,
Convertible
不需要是泛型的,因为它的转换函数不需要参数。最后,您不应该为您的类型同时声明
type
val

类型索引=Int
整型=Int
类型Real=Double
性状转换{
def toIndex:索引
def toInteger:整数
真的吗
}
//隐式类不能在顶级作用域中定义,因此它们属于对象。
对象隐式{
隐式类可转换元素(i:Int)
延伸敞篷车{
覆盖def toIndex=i
覆盖def toInteger=i
覆盖def toReal=i.toDouble
}
隐式类ConvertibleDouble(d:Double)
延伸敞篷车{
覆盖def toIndex=d.toInt
覆盖def toInteger=d.toInt
覆盖def toReal=d
}
隐式类可转换限制: