为了账号安全,请及时绑定邮箱和手机立即绑定

<:<、<%<和=Scala2.8中的平均值是什么?

<:<、<%<和=Scala2.8中的平均值是什么?

<:<、<%<和=Scala2.8中的平均值是什么?我可以在api文档中看到普雷德夫它们是泛型函数类型(From)=>to的子类,但它只说明了这一点。嗯,什么?也许在某个地方有文档,但是搜索引擎没有处理“<:<”之类的“名称”-非常好,所以我一直找不到它。后续问题:我什么时候应该使用这些时髦的符号/类,为什么?
查看完整描述

3 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

这些叫做广义类型约束..它们允许您从类型参数化类或特征中,到进一步约束它的一个类型参数。下面是一个例子:

case class Foo[A](a:A) { // 'A' can be substituted with any type
    // getStringLength can only be used if this is a Foo[String]
    def getStringLength(implicit evidence: A =:= String) = a.length}

隐式论证evidence由编译器提供,如果AString..你可以把它想象成证明那,那个AString-争论本身并不重要,只是知道它的存在。编辑:从技术上讲,它实际上很重要,因为它代表了从AString,这就是你可以打电话给a.length不要让编译器对你大喊大叫]

现在我可以这样使用它了:

scala> Foo("blah").getStringLength
res6: Int = 4

但如果我试着用它Foo包含其他东西,而不是String:

scala> Foo(123).getStringLength<console>:9: error: could not find implicit value for parameter evidence: =:=[Int,String]

您可以将该错误理解为“无法找到int=string的证据”.应该是这样的!getStringLength气势磅礴进一步限制关于…的类型A比什么Foo一般需要;也就是说,您只能调用getStringLength在.上Foo[String]..这个约束是在编译时强制执行的,这很酷!

<:<<%<工作方式类似,但略有变化:

  • A =:= B

    意思是A一定就是B
  • A <:< B

    表示A必须是B的子类型(类似于

    简约

    类型约束

    <:)

  • A <%< B

    意思是A必须是

    可见

    作为B,可能通过隐式转换(类似于简单类型约束)。

    <%)

这个片段很好地解释了这类事情过去是如何完成的,以及广义类型约束如何使它现在变得更容易。

增编

要回答你的后续问题,无可否认,我给出的例子是相当人为的,显然没有用。但是想象一下使用它来定义类似于List.sumInts方法,该方法将整数列表相加。您不希望在任何旧方法上调用此方法List,只是一个List[Int]..但是List类型构造函数不能受到如此的约束;您仍然希望能够有字符串、foos、条形图和诸如此类的列表。因此,通过在sumInts,你可以确保就是那种方法有一个附加约束,只能在List[Int]..实际上,你是在为某些类型的列表编写特例代码。


查看完整回答
反对 回复 2019-07-11
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

不是一个完整的答案(其他人已经回答了这个问题),我只想指出以下几点,这可能有助于更好地理解语法:您通常使用这些“操作符”的方式,例如在Pelotom的示例中:

def getStringLength(implicit evidence: A =:= String)

利用Scala的选择类型运算符的infix语法.

所以,A =:= String是相同的=:=[A, String](和=:=只是一个有着花哨名字的类别或特征)。请注意,这个语法也适用于“常规”类,例如,您可以编写:

val a: Tuple2[Int, String] = (1, "one")

就像这样:

val a: Int Tuple2 String = (1, "one")

它类似于方法调用的两个语法,即“Normal”.()以及运算符语法。


查看完整回答
反对 回复 2019-07-11
?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

阅读其他答案,了解这些构造是什么。这是什么时候你应该用它们。当只需要对特定类型的方法进行约束时,可以使用它们。

下面是一个例子。假设您想定义一个同构对,如下所示:

class Pair[T](val first: T, val second: T)

现在要添加一个方法smaller,就像这样:

def smaller = if (first < second) first else second

只有在T是被命令的。您可以限制整个类:

class Pair[T <: Ordered[T]](val first: T, val second: T)

但这似乎是个耻辱-当T不是命令。使用类型约束,仍然可以定义smaller方法:

def smaller(implicit ev: T <:< Ordered[T]) = if (first < second) first else second

实例化,比如说,Pair[File]只要你不打电话 smaller在上面。

如属Option,实现者希望orNull方法,尽管它没有意义Option[Int]..通过使用类型约束,一切都很好。你可以用orNull在.上Option[String],您可以形成一个Option[Int]使用它,只要你不打电话orNull在上面。如果你试着Some(42).orNull,你得到了迷人的信息

 error: Cannot prove that Null <:< Int


查看完整回答
反对 回复 2019-07-11
  • 3 回答
  • 0 关注
  • 6804 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信