gpt4 book ai didi

scala - generic bounds,大部分不清楚

转载 作者:行者123 更新时间:2023-12-02 00:05:21 25 4
gpt4 key购买 nike

学习 Scala 的泛型边界有点复杂。我知道:

T : Tr - T类型为 Tr ,意味着它实现了一个trait Tr

T <: SuperClass - TSuperClass 的子类

T :> ChildClass - TChildClass 的父类(super class)

但是,还有更多的运算符:

<%%>

=:=

<:<>:>

<%%>

<%<>%>

我读过它们,但正如我所说,没有可理解的解释。你能说得更清楚吗?

最佳答案

我使用了一些类型约束:

  1. 最简单的是 <:>: .这些是类型层次结构的简单界限。

    trait A
    trait B extends A
    trait C extends B

    然后是一个方法

    def doSomething[T >:C <:B](data:T)

    或者BC可以代替T

  2. 然后键入涉及向方法添加隐式参数的约束。

    def doSmth1[T: MyTypeInfo] (data:T)

    在编译期间重写为

    def doSmth1[T] (data:T)(implicit ev: MyTypeInfo[T])

    鉴于

    def doSmth2[T <% SomeArbitratyType] (data:T)

    改写为

    def doSmth2[T] (data:T)(implicit ev: T => SomeArbitratyType)

    如果在范围内有一个适合隐式参数的实例,则可以调用这两种方法。如果没有合适的实例,则编译器会发出错误。

    View 绑定(bind) ( <% ) 需要一个隐式转换来转换 T到另一种类型的实例 ( SomeArbitratyType )。

    更强大的是使用“类型类”。在类型类实例中,可以放置许多可以处理类型 T 的有用方法。 .特别是,可以放置一种转换方法并获得与 View 边界类似的结果。

    例子:

    trait MyTypeInfo[T] {
    def convertToString(data:T):String
    }
    def printlnAdv[T : MyTypeInfo](data:T) {
    val ev = implicitly[MyTypeInfo[T]]
    println(ev.convertToString(data))
    }

    范围内的某处应该有 MyTypeInfo[T] 类型的隐式值:

    implicit val doubleInfo = new MyTypeInfo[Double] {
    def convertToString(data:Double):String = data.toString
    }

    implicit def convertToString(data:T):String

    def printlnAdv[T <% String](data:T) {
    val conversionResult = data : String
    println(conversionResult)
    }

    范围内的某处应该有隐式函数:

    implicit def convertDoubleToString(data:Double):String = data.toString
  3. 下一个奇怪的符号是=:=<:< .这些用于希望确保类型具有某些属性的方法中。当然,如果你声明了一个泛型参数,那么 <: 就足够了。和 >:指定类型。但是,如何处理不是泛型参数的类型?例如,封闭类的泛型参数,或在另一种类型中定义的某种类型。这些符号在这里有帮助。

    trait MyAlmostUniversalTrait[T] {
    def mySpecialMethodJustForInts(data:T)(implicit ev:T =:= Int)
    }

    特征可用于任何类型 T .但是只有为 Int 实例化特征时才能调用该方法.

    <:< 存在类似的用例.但这里我们没有“等于”约束,而是“小于”约束(如 T<: T2 )。

    trait MyAlmostUniversalTrait[T] {
    def mySpecialMethod(data:T)(implicit ev:T <:< MyParentWithInterestingMethods)
    }

    同样,该方法只能为 MyParentWithInterestingMethods 的后代类型调用.

  4. 然后 <%<<% 非常相似, 但它的使用方式与 <:< 相同— 当类型不是泛型参数时作为隐式参数。它转换为 T2 :

    trait MyAlmostUniversalTrait[T] {
    def mySpecialMethod(data:T)(implicit ev:T <%< String) {
    val s = data:String
    ...
    }
    }

    恕我直言<%<可以安全地忽略。并且可以简单地声明所需的转换函数:

    trait MyAlmostUniversalTrait[T] {
    def mySpecialMethod(data:T)(implicit ev:T => String) {
    val s = data:String
    ...
    }
    }

关于scala - generic bounds,大部分不清楚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18744937/

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