Scala:转换一个对象并将其分配给一个变量

Scala: cast an object and assign it to a variable

我想将 myObject 转换为特定的 class 并将其分配给变量 myTargetObject。我有以下 Scala 代码,但在转换时出现错误:

  def findResult[T](myObject: T): String = {

    var myTargetObject= None

    if (myObject.isInstanceOf[myClass1]) {
      myTargetObject = myObject.asInstanceOf[myClass1]

    } else if (myObject.isInstanceOf[myClass2]) {
      myTargetObject = myObject.asInstanceOf[myClass2]

    } else (myObject.isInstanceOf[myClass3]) {
      myTargetObject = myObject.asInstanceOf[myClass3]
    }  
}

为此,正确的语法应该是什么?非常感谢!

问题是当您执行 var myTargetObject= None 时,它推断类型为 Option[Any] None,因此尝试将其重新分配为myClassN 会失败。

正确的做法是匹配:

def findResult[T](myObject: T): String = {
  myObject match{
    case myTargetObject:MyClass1 => {
      //Actions for MyClass1
    }
    case myTargetObject:MyClass2 => {
      //Actions for MyClass2
    }
    case myTargetObject:MyClass3 => {
      //Actions for MyClass3
    }
    case other => {
      //Default action
    }
  }
}

这样您就可以将其用作所需的类型,同时仍然是完全类型安全的。尽管这仍然不太理想,因为您通常不希望行为专门针对调用代码中的每个 class。您应该尝试将其重构为使用通用接口,以便可以以相同的方式处理它。

恕我直言,在 Scala 中最惯用的方法是使用类型 类:

class MyClass1(val s: String)

class MyClass2(val s: String)

trait ResultFinder[T] {
  def findResult(t: T): String
}

object ResultFinder {
  def findResult[T: ResultFinder](t: T): String = implicitly[ResultFinder[T]].findResult(t)

  implicit object RFMyClass1 extends ResultFinder[MyClass1] {
    override def findResult(t: MyClass1): String = t.s + " of MyClass1"
  }

  implicit object RFMyClass2 extends ResultFinder[MyClass2] {
    override def findResult(t: MyClass2): String = t.s + " of MyClass2"
  }
}

REPL 会话:

scala> import ResultFinder.findResult
import ResultFinder.findResult

scala> val c1 = new MyClass1("hello")
c1: MyClass1 = MyClass1@39fb3ab6

scala> val c2 = new MyClass2("hello")
c2: MyClass2 = MyClass2@3fee9989

scala> findResult(c1)
res0: String = hello of MyClass1

scala> findResult(c2)
res1: String = hello of MyClass2

这个解决方案是完全类型安全的。没有演员表,甚至没有幕后花絮。相反,模式匹配技术使用引擎盖下的转换。这个解决方案的另一个好处是它适用于更复杂的类型,如 List[MyClass1] ,前提是范围内有它的隐式实例。由于类型擦除,模式匹配不适用于 List[MyClass1]

P.S.: 我想你使用 myTargetObject 作为 temp 变量,但你实际上并不需要它,因为唯一的方法是 走出 of findResult 有意义的是返回一个 String.