scala在什么情况下正确地将字符串转换为java.lang.String

scala在什么情况下正确地将字符串转换为java.lang.String,java,string,scala,templates,generics,Java,String,Scala,Templates,Generics,假设我创建了一个单参数泛型方法: trait MyTrait[T] { def method():T } 然后扩展它并参数化。这: class MyClass extends MyTrait[java.lang.String] { def method() = "foo" } 与此相同: class MyClass extends MyTrait[String] { def method() = "foo" } 但是,当您使用trait方法参数化lambda时,如下所示: tr

假设我创建了一个单参数泛型方法:

trait MyTrait[T] {
  def method():T
}
然后扩展它并参数化。这:

class MyClass extends MyTrait[java.lang.String] {
  def method() = "foo"
}
与此相同:

class MyClass extends MyTrait[String] {
  def method() = "foo"
}
但是,当您使用trait方法参数化lambda时,如下所示:

trait MyTrait {
  def apply[T](input:()=>T):T
}
那你就没那么幸运了。这:

class MyClass extends MyTrait {
  def apply(input:()=>java.lang.String) = "foo"
}
这将导致:

Error:(25, 45) type mismatch;
 found   : java.lang.String("foo")
 required: String
      def apply[String](input:()=>String) = "foo"
                                    ^
然而,这很好:

class MyClass extends MyTrait {
  def apply[String](input:()=>String) = new String("foo")
}
那么scalac在什么情况下知道需要进行转换,在什么情况下不知道

此外,即使我写出java.lang.String类型的整个路径

class MyClass extends MyTrait {
  def apply[java.lang.String](input:()=>java.lang.String) = new java.lang.String("foo")
}
它抛出另一个错误:

Error:(25, 21) ']' expected but '.' found.
      def apply[java.lang.String](input:()=>java.lang.String) = new java.lang.String("foo")
                    ^
如果我想通过直接模板化java.lang.String来实现后一种方式,我该怎么做呢

class MyClass extends MyTrait {
  def apply[String](input:()=>String) = new String("foo")
}
这不好。它导致需要
类类型,但找到字符串
。这里的问题是,在使用参数化方法扩展类时,没有声明类型参数是什么。在使用该方法时声明它

让我们重写一下:

class MyClass extends MyTrait {
  def apply[String](input:()=>String) = input()
}
现在请注意:

scala> (new MyClass).apply[String](() => "foo")
res0: String = foo

scala> (new MyClass).apply[Int](() => 5)
res1: Int = 5
它之所以有效,是因为当您声明以下内容时:

  def apply[String](input:()=>String) = input()
String
是参数的名称。如果您编写了
T
xyzy
,或
maniskattypepartameters
而不是上面的
String
,则情况完全相同。您的意思是,您将获得一个类型参数,您将命名类型参数
String
,这是返回函数的值,通过重写,
apply
方法的值

当我调用
apply[Int](()=>5)
时,Scala将用
Int
替换定义中的
String

class MyClass extends MyTrait {
  def apply[String](input:()=>String) = new String("foo")
}
这不好。它导致需要
类类型,但找到字符串
。这里的问题是,在使用参数化方法扩展类时,没有声明类型参数是什么。在使用该方法时声明它

让我们重写一下:

class MyClass extends MyTrait {
  def apply[String](input:()=>String) = input()
}
现在请注意:

scala> (new MyClass).apply[String](() => "foo")
res0: String = foo

scala> (new MyClass).apply[Int](() => 5)
res1: Int = 5
它之所以有效,是因为当您声明以下内容时:

  def apply[String](input:()=>String) = input()
String
是参数的名称。如果您编写了
T
xyzy
,或
maniskattypepartameters
而不是上面的
String
,则情况完全相同。您的意思是,您将获得一个类型参数,您将命名类型参数
String
,这是返回函数的值,通过重写,
apply
方法的值


当我调用
apply[Int](()=>5)
时,Scala会将定义中的
String
替换为
Int
def apply[String]
您在这里声明的是名为
String
的类型参数。
def apply[String]
您在这里声明的是名为
String
的类型参数。哇,我真是太傻了。谢谢你的回复。哎呀,我真是太傻了。谢谢你的回复。