我有一个返回的函数(groovy代码)
[words: "one two", row: 23, col: 45]
Run Code Online (Sandbox Code Playgroud)
在scala中,我将上面更改为scala Map,但后来我被迫将其声明为
Map[String, Any]
Run Code Online (Sandbox Code Playgroud)
但是这样做的缺点是,如果我访问一个键,例如map("words"),我必须添加样板
map2("words").asInstanceOf[String]
Run Code Online (Sandbox Code Playgroud)
在scala中是否有更好的方法不需要我添加asInstanceOf?
kas*_*ens 11
为了避免强制转换并从静态类型中获益,您可以返回一个元组(String, Int, Int):
def getResult = ("one two", 23, 45)
val res = getResult
res._1 // the line
// alternatively use the extractor
val (line, row, _) = getResult // col is discarded
line // the line
row // the row
Run Code Online (Sandbox Code Playgroud)
或者为结果使用案例类:
case class MyResult(line: String, row: Int, col: Int)
def getResult = MyResult("one two", 23, 45)
val res = getResult
res.line // the line
// alternatively use the extractor provided by the case class
val MyResult(line, row, _) = getResult // col is discarded
line // the line
row // the row
Run Code Online (Sandbox Code Playgroud)
我更喜欢case类,因为字段是命名的,它实际上只是一行.
这是案例类是你的朋友的地方.如果您的地图的键是案例类,那么您可以强制客户端代码正确处理类型(并强制它正确处理所有类型).
S:\>scala
Welcome to Scala version 2.9.0.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> sealed abstract class Thing;
defined class Thing
scala> case class Toaster(slices: Int) extends Thing;
defined class Toaster
scala> case class Bucket(contents: String) extends Thing;
defined class Bucket
scala> val things = Map("toasty" -> Toaster(2), "buck" -> Bucket("stuff"));
things: scala.collection.immutable.Map[java.lang.String,Product with Serializable with Thing] = Map(toasty -> Toaster(2), buck -> Bucket(stu
ff))
scala> for (x <- things) x match {
case (k,Toaster(s)) => println(k + " " + s)
case (k,Bucket(c)) => println(k + " " + c)
}
toasty 2
buck stuff
Run Code Online (Sandbox Code Playgroud)
这里的关键是匹配语句可以解决各种情况,并为您提供正确的类型变量以匹配其中的字段.通过声明抽象类是密封的,您可以让编译器知道它具有所有可用的子类.通过该信息,它可以告诉您何时丢失案例,并且还可以进行进一步优化.
| 归档时间: |
|
| 查看次数: |
6763 次 |
| 最近记录: |