- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
学习 Scala 的泛型边界有点复杂。我知道:
T : Tr
- T
类型为 Tr
,意味着它实现了一个trait Tr
T <: SuperClass
- T
是 SuperClass
的子类
T :> ChildClass
- T
是 ChildClass
的父类(super class)
但是,还有更多的运算符:
<%
和 %>
=:=
<:<
和 >:>
<%
和 %>
<%<
和 >%>
我读过它们,但正如我所说,没有可理解的解释。你能说得更清楚吗?
最佳答案
我使用了一些类型约束:
最简单的是 <:
和 >:
.这些是类型层次结构的简单界限。
trait A
trait B extends A
trait C extends B
然后是一个方法
def doSomething[T >:C <:B](data:T)
或者B
或 C
可以代替T
然后键入涉及向方法添加隐式参数的约束。
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
下一个奇怪的符号是=:=
和 <:<
.这些用于希望确保类型具有某些属性的方法中。当然,如果你声明了一个泛型参数,那么 <:
就足够了。和 >:
指定类型。但是,如何处理不是泛型参数的类型?例如,封闭类的泛型参数,或在另一种类型中定义的某种类型。这些符号在这里有帮助。
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
的后代类型调用.
然后 <%<
与 <%
非常相似, 但它的使用方式与 <:<
相同— 当类型不是泛型参数时作为隐式参数。它转换为 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/
MVC3 中的助手是否在 Controller 和 View 中使用? 助手是放置常用 Controller 方法的正确位置吗? 我想创建一个通用方法来获取数据库中的所有子子 ID,并确保它位于正确的
有人可以阐明这两者之间的区别吗,因为它们存在于执行上下文中?我很难阅读 ECMA 262 v 5规范并清楚地看到差异。 谢谢你, 最佳答案 两者都是执行上下文的组件(相同类型),但它们有不同的用途(f
我是一名优秀的程序员,十分优秀!