簡體   English   中英

這個“簡單”ScalaZ教程代碼示例中的隱式解析序列是什么?

[英]What is the implicit resolution sequence in this “simple” ScalaZ tutorial code example?

下面的代碼片段取自 ScalaZ教程。

在評估代碼示例底部的10.truthy時,我無法弄清楚隱式解析規則是如何應用的。

我認為 - 我明白的事情如下:

1)隱含值intCanTruthyCanTruthy[A]的匿名子類的實例,它CanTruthy[A]內容定義Int -s的truthys方法:

scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
         case 0 => false
         case _ => true
       })
intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1@71780051

2)當評估10.truthytoCanIsTruthyOps隱式轉換方法在范圍內,因此當編譯器看到Int沒有truthy方法時,它將嘗試使用這種隱式轉換方法。 所以編譯器會嘗試尋找它轉換一些隱式轉換方法10進入的對象不具有truthy方法及其它會嘗試toCanIsTruthyOps這種轉換是。

3)我懷疑當編譯器在10上嘗試toCanIsTruthyOps隱式轉換時,可能會以某種方式使用隱式值intCanTruthy

但這是我真正迷失的地方。 我只是沒有看到隱含的解決方法過程如何進行。 接下來發生什么 ? 怎么樣,為什么?

換句話說,我不知道什么是隱式解析序列,它允許編譯器在評估10.truthy時找到truthy方法的實現。

問題

如何將10轉換為具有正確truthy方法的某個對象?

那個對象是什么?

那個對象來自哪里?

有人可以詳細解釋在評估10.truthy時隱式解決方案是如何發生的嗎?

CanTruthy中的自我類型 { self => ... CanTruthy在隱式解決過程中發揮作用?

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait CanTruthy[A] { self =>
  /** @return true, if `a` is truthy. */
  def truthys(a: A): Boolean
}
object CanTruthy {
  def apply[A](implicit ev: CanTruthy[A]): CanTruthy[A] = ev
  def truthys[A](f: A => Boolean): CanTruthy[A] = new CanTruthy[A] {
    def truthys(a: A): Boolean = f(a)
  }
}
trait CanTruthyOps[A] {
  def self: A
  implicit def F: CanTruthy[A]
  final def truthy: Boolean = F.truthys(self)
}
object ToCanIsTruthyOps {
  implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A]) =
    new CanTruthyOps[A] {
      def self = v
      implicit def F: CanTruthy[A] = ev
    }
}

// Exiting paste mode, now interpreting.

defined trait CanTruthy
defined module CanTruthy
defined trait CanTruthyOps
defined module ToCanIsTruthyOps

嘗試10上的類型類:

scala> import ToCanIsTruthyOps._
import ToCanIsTruthyOps._

scala> implicit val intCanTruthy: CanTruthy[Int] = CanTruthy.truthys({
         case 0 => false
         case _ => true
       })
intCanTruthy: CanTruthy[Int] = CanTruthy$$anon$1@71780051

scala> 10.truthy
res6: Boolean = true

首先,感謝您粘貼一個完全獨立的示例。

如何將10轉換為具有正確truthy方法的某個對象?

當對類型A不提供該方法的值調用方法時,必須啟動隱式轉換 ,即在范圍內必須有方法或函數,其中簽名A => B其中B具有所討論的方法( truthy )。 在轉換方法的情況下,它可能要求額外的隱含參數 ,這些參數將被相應地查找。

轉換方法是toCanIsTruthyOps ,通過導入ToCanIsTruthyOps的內容使其可用。 上述句子中的B型是CanTruthyOps ,轉換方法是toCanIsTruthyOps 只要找到隱式類型類證據參數CanTruthy它就可以被編譯器調用。 因此,由於type A = Int ,如果調用10.truthy將成功,編譯器必須找到CanTruthy[Int]類型的隱式值。

它在幾個地方尋找這樣的價值。 它可能位於Int (不存在)的伴隨對象或CanTruthy的伴隨對象中,或者顯式導入到當前范圍中。 這里使用最后一種情況。 您明確創建了隱式值intCanTruthy ,現在找到該值。 就是這樣。

那個對象是什么?

將有一個CanTruthyOps的臨時實例,其目的僅僅是在證據類型類值上調用truthys (這里是你的intCanTruthy )。

那個對象來自哪里?

它在查找隱式轉換時發現Int => CanTruthyOps[Int] 轉換執行該對象的實例化。

有人可以詳細解釋在評估10.truthy時隱式解決方案是如何發生的嗎?

請參閱上面第一個問題的答案。 或者作為顯式代碼:

type A = Int
val v: A = 10
val ev: CanTruthy[A] = intCanTruthy
val ops: CanTruthyOps[A] = ToCanIsTruthyOps.toCanIsTruthyOps(v)(ev)
ops.truthy

CanTruthy中的自我類型{ self => ... CanTruthy在隱式解決過程中發揮作用?

它與隱式解決方案無關。 事實上,在你們的例子trait CanTruthy中, self充當一個別名this並沒有使用連,所以你可以只將其刪除。

將任何A轉換為具有truthy方法的CanTruthyOps[T]的方法的truthy是:

implicit def toCanIsTruthyOps[A](v: A)(implicit ev: CanTruthy[A])

這意味着它不會轉換任何A而只會轉換那些定義了CanTruthy[A]CanTruthy[A] ,這就是implicit ev參數的用途。 這意味着,作為將10映射到具有.truthy方法的事物的過程的一部分,在完成包裝之前也會intCanTruthy 因此,當10被隱式轉換為具有truthy方法的東西時, intCanTruthy實例將被查找並作為CanTruthyOpsF屬性存儲起來:

implicit def F: CanTruthy[A] = ev

(實際上我不知道為什么implicit在那里是必要的; truthy()將明確轉向F

F.truthys(self)

至於隱式解析是如何工作的,最好還是查找詳細描述該過程的文檔。

暫無
暫無

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

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