隐式和召唤有啥区别?
Posted
技术标签:
【中文标题】隐式和召唤有啥区别?【英文标题】:What's the difference between implicitly and summon?隐式和召唤有什么区别? 【发布时间】:2021-09-23 00:12:32 【问题描述】:在 Scala 3 中 summon
似乎与旧的 implicitly
做同样的事情。但是,当我们深入研究实际示例时,我们发现情况并非如此。例如
case class A(i: Int, s: String)
val mirror = implicitly[Mirror.Of[A]]
type ValueOfs = Tuple.Map[mirror.MirroredElemLabels, ValueOf]
val valueOfs = summonAll[ValueOfs]
def values(t: Tuple): Tuple = t match
case (h: ValueOf[_]) *: t1 => h.value *: values(t1)
case EmptyTuple => EmptyTuple
产生错误
cannot reduce inline match with
scrutinee: compiletime.erasedValue[App.ValueOfs] : App.ValueOfs
patterns : case _:EmptyTuple
case _:*:[t @ _, ts @ _]
但是用summon[Mirror.Of[A]]
替换implicitly[Mirror.Of[A]]
编译正常。
在这种情况下和一般情况下,summon
与 implicitly
的微妙之处是什么?
【问题讨论】:
This answer 可能是相关的。虽然我对 Scala 3 的Mirror
类型了解不多,无法将其与您的代码 sn-p 连贯地联系起来,所以我会让其他人来做这个荣誉。
summon
类似于shapeless.the
typelevel.org/blog/2014/01/18/implicitly_existential.html ***.com/questions/65634897/… ***.com/questions/65062041/… ***.com/questions/64438704/…
【参考方案1】:
给定
case class A(i: Int, s: String)
我们可以看到summon
和implicitly
返回相同的运行时值
assert(implicitly[Mirror.Of[A]] eq summon[Mirror.Of[A]])
但它们有不同的编译时间类型
def fun[A,B]( a: A, b: B )( implicit ev: A =:= B ) = ???
fun(implicitly[Mirror.Of[A]], summon[Mirror.Of[A]])
Cannot prove that deriving.Mirror.Of[Worksheet.A] =:= (
deriving.Mirror
MirroredType = Worksheet.A; MirroredMonoType = Worksheet.A;
MirroredElemTypes <: Tuple
&
scala.deriving.Mirror.Product
MirroredMonoType = Worksheet.A; MirroredType = Worksheet.A;
MirroredLabel = ("A" : String)
)
MirroredElemTypes = (Int, String);
MirroredElemLabels = (("i" : String), ("s" : String))
.
summon
返回的更具体,尽管我不确定这如何/为什么适用于问题中的情况。
【讨论】:
以上是关于隐式和召唤有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章