簡體   English   中英

Scala隱式和類型別名

[英]Scala implicits and type aliases

假設我有以下代碼:

object Potato extends App {

  type CoolString = String
  type AwesomeString = String

  def potato(string: String)(implicit coolString: CoolString, awesomeString: AwesomeString) = {
    s"$string is a string. Oh, but don't forget - $coolString and also $awesomeString"
  }

  implicit val ice : CoolString = "Really Cold Ice"
  implicit val awe : AwesomeString = "Awe inspiring object"

  potato("Stringerino")

}

此代碼失敗並出現問題

[error] ... ambiguous implicit values:
[error]  both value ice in object Potato of type => Potato.CoolString
[error]  and value awe in object Potato of type => Potato.AwesomeString
[error]  match expected type Potato.CoolString
[error]   potato("Stringerino")

這樣隱式的使用是不可能的嗎?

這樣隱式的使用是不可能的嗎?

不僅不可能,而且依賴於將String這樣的常規類型作為隱式接受這種方法也是危險的。 考慮一下,范圍內的任何String實例都將是合格的候選者,可以被傳遞到方法中!

類型別名就是類型別名,僅此而已。 對於編譯器, CoolStringAwesomeString都只是String

更好的方法是利用標記類型。 例如,這是使用shapeless標記類型

import shapeless.tag.@@

trait CoolString
trait AwesomeString

type ReallyCoolString = String @@ CoolString
type ReallyAwesomeString = String @@ AwesomeString

接着:

import shapeless.tag

def potato(string: String)(implicit coolString: ReallyCoolString, awesomeString: ReallyAwesomeString) = {
  s"$string is a string. Oh, but don't forget - $coolString and also $awesomeString"
}

def main(args: Array[String]): Unit = {
  implicit val ice = tag[CoolString][String]("Really Cold Ice")
  implicit val awe = tag[AwesomeString][String]("Awe inspiring object")

  println(potato("Stringerino"))
}

產量:

Stringerino is a string. 
Oh, but don't forget - Really Cold Ice and also Awe inspiring object

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM