0

现在我不是假装这段代码是好的编程习惯,但我不明白为什么它不会编译。这里发生了什么?

object CustomTo extends App {
  val thing:Something = new Something
  val str:String = thing.to[String]
  println(str)
}

class Something {
  def to[String]:String = {
    "hello"
  }
}

编译器输出:

CustomTo.scala:9: error: type mismatch;
 found   : java.lang.String("hello")
 required: String
    "hello"
    ^
one error found
4

2 回答 2

1

您命名了您的类型参数String而不是T,但这并没有降低它的抽象性,它仍然可以是任何东西。

def to[String]:String 
// is the same as
def to[T]:T

如果您想创建一个.to[T]在使用 调用时返回 hello 的通用函数String,即您想对一个类型进行模式匹配,您可以使用 TypeTag

编辑:我只是忽略了返回类型需要是T,这意味着必须有一个无用的演员表,见下文。

import reflect.runtime.universe._

def to[T : TypeTag] = (typeOf[T] match {
  case t if t =:= typeOf[String] => "hello"
  case t if t =:= typeOf[Int] => 1
  case _ => ???
}).asInstanceOf[T]

和:

scala> to[String]
res13: String = hello

scala> to[Int]
res14: Int = 1

scala> to[Double]
scala.NotImplementedError: an implementation is missing
...

我不确定是否有办法让编译器自行推断模式匹配中的内容具有正确的类型。可能有可能ClassTag,但你会失去类型安全.to[List[Int]]和类似......

于 2013-06-20T15:28:23.540 回答
0

编译器需要“字符串”,如果你把

class Something {
  def to[T]:T = {
    "hello"
  }
}

你会得到类似的东西"required: T"。换句话说,您将“字符串”绑定到某种类型。现在你的例子没有多大意义。你想达到什么目的?

于 2013-06-20T15:10:26.893 回答