3 回答
TA贡献1828条经验 获得超3个赞
类的类型参数。上下文约束是形式上的[T: Bound]
,它被扩展为普通类型参数。T
与类型的隐式参数一起使用。Bound[T]
.
考虑一下方法tabulate
它由对从0到给定长度的数字范围内应用给定函数f的结果形成数组。到Scala2.7,表格可以写成如下:
def tabulate[T](len: Int, f: Int => T) = { val xs = new Array[T](len) for (i <- 0 until len) xs(i) = f(i) xs}
在Scala2.8中,这已经不可能了,因为创建正确的表示形式需要运行时信息。Array[T]
..需要通过传递ClassManifest[T]
作为隐式参数进入该方法:
def tabulate[T](len: Int, f: Int => T)(implicit m: ClassManifest[T]) = { val xs = new Array[T](len) for (i <- 0 until len) xs(i) = f(i) xs}
作为速记形式,上下文约束可用于类型参数。T
相反,给予:
def tabulate[T: ClassManifest](len: Int, f: Int => T) = { val xs = new Array[T](len) for (i <- 0 until len) xs(i) = f(i) xs}
TA贡献1786条经验 获得超12个赞
在Scala中,视图绑定(A <% B
)抓住了“可以视为”的概念(而上界则是<:
捕捉“is a”的概念)。上下文约束(A : C
)说“有一种类型”。您可以将有关清单的示例阅读为“T
有一个Manifest
“.您链接到的关于Ordered
VSOrdering
说明了不同之处。一种方法
def example[T <% Ordered[T]](param: T)
表示该参数可视为Ordered
..相比较
def example[T : Ordering](param: T)
,该参数具有关联的Ordering
.
就使用而言,需要一段时间才能建立约定,但上下文界限比视图边界更可取(视图边界现在不再受欢迎。)。一种建议是,当您需要将隐式定义从一个作用域转移到另一个作用域时,上下文绑定是首选的,而不需要直接引用它(对于ClassManifest
用于创建数组)。
另一种考虑视图边界和上下文边界的方法是,第一种方法是从调用方的作用域传递隐式转换。第二个从调用者的作用域传输隐式对象。
TA贡献1799条经验 获得超9个赞
scala> implicit def int2str(i: Int): String = i.toString int2str: (i: Int)Stringscala> def f1[T <% String](t: T) = 0f1: [T](t: T)(implicit evidence$1: (T) => String)Int
F
T
.
scala> trait To[T] { type From[F] = F => T } defined trait Toscala> def f2[T : To[String]#From](t: T) = 0 f2: [T](t: T)(implicit evidence$1: (T) => java.lang.String)Intscala> f2(1)res1: Int = 0
* => *
Function1
(*, *) => *
String
def f3[T : [X](X => String)](t: T) = 0
- 3 回答
- 0 关注
- 531 浏览
添加回答
举报