gpt4 book ai didi

scala - 什么时候在 Scala 中使用隐式参数是有意义的,还有什么可以考虑的替代 scala 习惯用法?

转载 作者:行者123 更新时间:2023-12-04 22:46:06 26 4
gpt4 key购买 nike

使用了一个 Scala 库,它自由地向调用者公开了对隐式的依赖,我在这种机制上遇到了摩擦,因为 Scala 有时很难调试隐式参数,而且因为有很多地方 Scala 会填充值对于来自的隐式参数。 (我几乎可以一次将其称为“隐含 hell ”)。

有一次在我的编码中,Scala“提示”一个隐式值无法匹配,而实际上存在一个隐式值的“冲突”,每个隐式值都来自不同的导入。

不管感知到的脆弱性如何,它有时可能会让人觉得滥用上下文设计模式的边缘。

为什么在 Scala 中使用隐式参数有意义?
你会在什么场景下使用它们,你会如何避免麻烦?

由于我不确定其他团队成员完全困惑的实验曲线和潜力是否值得,您能否建议其他 scala 习惯用法在众多 Scala 函数之间共享上下文?

这个问题不适用于手头的特定实现,希望它仍然适合该站点。

最佳答案

通常,使用通用类型作为隐式参数是一个坏主意。

def badIdea(n: Int)(implicit s: String) = s * n

不难想象为什么:如果其他人采用此策略,您将在同一件事上得到相互矛盾的暗示。最好避免它。

但是谁真的想手动填充 scala.concurrent.ExecutionContext每次需要时手动(几乎无处不在)?

所以关键是:当你有一个特殊类型的东西时,特别是如果它的簿记可能需要手动覆盖,但大多数情况下应该做正确的事情,然后使用隐式参数。 (这通常也涵盖类型类。)

如果你真的需要一个字符串,你会怎么做?好吧,把它包装起来(至少在形式上——这里它是一个值类,所以在某些情况下它只会传递字符串):
class MyWrappedString(val underlying: String) extends AnyVal {}
implicit val myString = new MyWrappedString("bird")
def decentIdea(n: Int)(implicit mws: MyWrappedString) = mws.underlying * n

scala> decentIdea(2) // In the bush?
res14: String = birdbird

或者,如果您认为一些额外的逻辑有帮助,请编写一个带有额外类型参数的包装器:
class ImplicitWithValue[K,V](val value: V) {
// Any extra generic logic goes here
}
object ImplicitWithValue {
class ValuePart[K] {
def apply[V](v: V) = new ImplicitWithValue[K,V](v)
}
private val genericValuePart = new ValuePart[Any]
private def typedValuePart[K] = genericValuePart.asInstanceOf[ValuePart[K]]
def apply[K] = typedValuePart[K]
}

那么你就可以
trait Marker1
implicit val implicit1 = ImplicitWithValue[Marker1]("fish")

def goodIdea(n: Int)(implicit ms: ImplicitWithValue[Marker1, String]) = ms.value * n

scala> goodIdea(3)
res17: String = fishfishfish

关于scala - 什么时候在 Scala 中使用隐式参数是有意义的,还有什么可以考虑的替代 scala 习惯用法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25453299/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com