Scala “a”是什么;“上下文约束”;在斯卡拉?
Scala 2.8的一个新特性是上下文边界。什么是上下文绑定,它在哪里有用 当然,我首先搜索了(例如,我找到了),但我找不到任何真正清晰详细的信息。你找到了吗?在阵列改进的背景下,它涵盖了新的上下文绑定功能 通常,具有上下文绑定的类型参数的形式为Scala “a”是什么;“上下文约束”;在斯卡拉?,scala,scala-2.8,context-bound,Scala,Scala 2.8,Context Bound,Scala 2.8的一个新特性是上下文边界。什么是上下文绑定,它在哪里有用 当然,我首先搜索了(例如,我找到了),但我找不到任何真正清晰详细的信息。你找到了吗?在阵列改进的背景下,它涵盖了新的上下文绑定功能 通常,具有上下文绑定的类型参数的形式为[T:bound];它与类型为Bound[T]的隐式参数一起扩展为普通类型参数T 考虑方法制表,它根据应用的结果形成一个数组 在从0到给定长度的数字范围内的给定函数f。在Scala 2.7之前,表格可以是 内容如下: def tabulate[T](le
[T:bound]
;它与类型为Bound[T]
的隐式参数一起扩展为普通类型参数T
考虑方法制表
,它根据应用的结果形成一个数组
在从0到给定长度的数字范围内的给定函数f。在Scala 2.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
}
作为一种简写形式,可以在类型参数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
}
def制表[T:ClassManifest](len:Int,f:Int=>T){
val xs=新阵列[T](len)
因为(iRobert的回答涵盖了上下文边界的技术细节。我将向您解释它们的含义
在Scala中,视图绑定(a(这是一个附加说明。请先阅读并理解其他答案。)
上下文边界实际上概括了视图边界
因此,给定用视图边界表示的代码:
scala> implicit def int2str(i: Int): String = i.toString
int2str: (i: Int)String
scala> def f1[T <% String](t: T) = 0
f1: [T](t: T)(implicit evidence$1: (T) => String)Int
上下文绑定必须与类型构造函数*=>*
一起使用。但是类型构造函数Function1
是类型(*,*)=>*
。类型别名的使用部分地应用了第二个类型参数和类型字符串
,从而生成正确类型的类型构造函数,用作上下文绑定
有一个建议,允许您直接在Scala中表示部分应用的类型,而无需在trait中使用类型别名。然后您可以编写:
def f3[T : [X](X => String)](t: T) = 0
这是另一个附加说明
例如,上下文绑定表示类型参数和类型类之间的“has-a”约束。换句话说,它表示特定类型类的隐式值存在的约束
当使用上下文绑定时,通常需要显示该隐式值。例如,给定约束T:Ordering
,通常需要Ordering[T]的实例满足约束的
,可以使用隐式
方法或稍微有用的上下文
方法访问隐式值:
def **[T : Numeric](xs: Iterable[T], ys: Iterable[T]) =
xs zip ys map { t => implicitly[Numeric[T]].times(t._1, t._2) }
或
此外,还可以查看所有类型的边界:这个优秀的答案比较/对比了上下文边界和视图边界:这是一个非常好的答案。你能解释一下f2定义中#From的含义吗?我不确定F类型是从哪里构造的(我说得对吗?)它被称为类型投影,引用类型到[String]的类型成员From
。我们没有为From
中的提供类型参数,因此我们引用的是类型构造函数,而不是类型。此类型构造函数是用作上下文绑定的正确类型--*->*
。这通过要求类型的隐式参数为[String]\From[t]来限制类型参数t
。展开类型别名,瞧,剩下的是Function1[String,T]
。应该是Function1[T,String]?“有”而不是“是”或“视为”对我来说,这是一个关键的洞见——在其他任何解释中都看不到这一点。拥有一个简单的英文版本,否则稍微有点神秘的运算符/函数,让我更容易理解——谢谢!@Ben Lings你所说的…“是什么意思?”有一个“关于类型…”?关于类型是什么?@jhegedus这是我的解析:“关于类型”表示A指类型。在面向对象设计中,短语“has A”通常用于描述对象关系(例如,Customer”有一个“Address”)。但这里的“has A”关系是类型之间的关系,而不是对象之间的关系。这是一个松散的类比,因为“has A”关系并不像OO设计中那样是固有的或通用的;客户总是有地址,但对于上下文绑定,a并不总是有C。相反,上下文绑定指定C[a]的实例必须隐式提供。我已经学习Scala一个月了,这是我在这个月看到的最好的解释!谢谢@Ben!@Ben Lings:谢谢,在花了这么长时间理解什么是上下文约束之后,你的回答非常有用。[有一个对我更有意义的解释]
scala> implicit def int2str(i: Int): String = i.toString
int2str: (i: Int)String
scala> def f1[T <% String](t: T) = 0
f1: [T](t: T)(implicit evidence$1: (T) => String)Int
scala> trait To[T] { type From[F] = F => T }
defined trait To
scala> def f2[T : To[String]#From](t: T) = 0
f2: [T](t: T)(implicit evidence$1: (T) => java.lang.String)Int
scala> f2(1)
res1: Int = 0
def f3[T : [X](X => String)](t: T) = 0
def **[T : Numeric](xs: Iterable[T], ys: Iterable[T]) =
xs zip ys map { t => implicitly[Numeric[T]].times(t._1, t._2) }
def **[T : Numeric](xs: Iterable[T], ys: Iterable[T]) =
xs zip ys map { t => context[T]().times(t._1, t._2) }