2015-07-17 13 views
5

Trong Scala 2.10, trình biên dịch cảnh báo mã số:Scala loại chô bôi trong mô hình phù hợp với Bản đồ [String, Int]

private def getStrFromOpt[T](opt: Option[T]): String = opt match { 
    case Some(s: String) => s 
    case Some(i: Int) => i.toString() 
    case Some(l: Long) => l.toString() 
    case Some(m: Map[String, Int]) => m map ({ case (k, v) => 
     "(" + k + ", " + v + ")" }) mkString ("(", ", ", ")") 
    case _ => "" 
    } 

với thông điệp non-variable type argument String in type pattern Map[String,Int] is unchecked since it is eliminated by erasure: case Some(m: Map[String, Int]) ....

Tôi làm cách nào để loại bỏ cảnh báo này? Điều gì sẽ xảy ra nếu tôi có một số Map[String, MyObj] mà tôi muốn đưa vào trường hợp trong kết hợp này - làm cách nào để phân biệt hai trường hợp với Bản đồ được tham số hóa?

+0

bản sao có thể có của [Làm cách nào để xóa bỏ loại xóa trên Scala? Hoặc, tại sao tôi không thể lấy thông số loại của bộ sưu tập của mình?] (Http://stackoverflow.com/questions/1094173/how-do-i-get-around-type-erasure-on-scala-or-why -cant-i-get-the-type-paramete) – Chirlo

Trả lời

4

bạn có thể sử dụng chú thích Scala @unchecked để chặn cảnh báo, cho câu hỏi thứ hai của bạn, tôi khuyên bạn nên sử dụng phản chiếu Scala - TypeTag. Tôi đang sử dụng Scala 2.11.4, đây là mã mẫu, FYI.

import scala.reflect.runtime.{ universe => ru } 
import scala.reflect.runtime.universe.{ typeTag, TypeTag } 

object MapType extends App { 
    def getTypeTag[T: TypeTag](t: T) = typeTag[T].tpe 
    def getTypeTag[T: TypeTag] = ru.typeOf[T] 

    // context bound T: ru.TypeTag cause typeOf 
    // requires implicit parameter 
    def getStrFromOpt[T: TypeTag](opt: Option[T]): String = { 
    opt match { 
     case Some(s: String) => s 
     case Some(i: Int) => i.toString() 
     case Some(l: Long) => l.toString() 
     case Some(m: Map[String, Int] @ unchecked) 
     if getTypeTag[T] =:= getTypeTag[Map[String, Int]] => "Int Map" 
     case Some(m: Map[String, String] @ unchecked) 
     if getTypeTag[T] =:= getTypeTag[Map[String, String]] => "String Map" 
     case _ => "" 
    } 
    } 

    // "Int Map" 
    println(getStrFromOpt(Some(Map("a" -> 2, "b" -> 3)))) 
    // "String Map" 
    println(getStrFromOpt(Some(Map("a" -> "2", "b" -> "3")))) 
} 

Thực ra, Scala sử dụng mô hình xóa của Generics giống như Java. Vì vậy, không có thông tin nào về các đối số kiểu được duy trì trong thời gian chạy.

def isIntMap(x: Any) = x match { 
    case m: Map[Int, Int] => true 
    case _ => false 
} 

Đối với mã ở trên, trình biên dịch Scala không thể quyết định liệu m là Map [Int, Int] hay không. Do đó, isIntMap(Map("a"-> "b")) trả về true, có vẻ không trực quan. Để cảnh báo bạn về hành vi thời gian chạy, trình biên dịch Scala đã phát ra thông báo chưa được kiểm tra đó.

Tuy nhiên, Mảng là một ngoại lệ, loại phần tử của nó được lưu trữ với giá trị phần tử.

def isIntArray(x: Any) = x match { 
    case a: Array[String] => "yes" 
    case _ => "no" 
} 

scala> isIntArray(Array(3)) 
res1: String = no 

scala> isIntArray(Array("1")) 
res2: String = yes 
Các vấn đề liên quan