猿问

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

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

我可以在api文档中看到普雷德夫它们是泛型函数类型(From)=>to的子类,但它只说明了这一点。嗯,什么?也许在某个地方有文档,但是搜索引擎没有处理“<:<”之类的“名称”-非常好,所以我一直找不到它。

后续问题:我什么时候应该使用这些时髦的符号/类,为什么?


四季花海
浏览 6805回答 3
3回答

慕容森

这些叫做广义类型约束..它们允许您从类型参数化类或特征中,到进一步约束它的一个类型参数。下面是一个例子:case&nbsp;class&nbsp;Foo[A](a:A)&nbsp;{&nbsp;//&nbsp;'A'&nbsp;can&nbsp;be&nbsp;substituted&nbsp;with&nbsp;any&nbsp;type &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;getStringLength&nbsp;can&nbsp;only&nbsp;be&nbsp;used&nbsp;if&nbsp;this&nbsp;is&nbsp;a&nbsp;Foo[String] &nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;getStringLength(implicit&nbsp;evidence:&nbsp;A&nbsp;=:=&nbsp;String)&nbsp;=&nbsp;a.length}隐式论证evidence由编译器提供,如果A是String..你可以把它想象成证明那,那个A是String-争论本身并不重要,只是知道它的存在。编辑:从技术上讲,它实际上很重要,因为它代表了从A到String,这就是你可以打电话给a.length不要让编译器对你大喊大叫]现在我可以这样使用它了:scala>&nbsp;Foo("blah").getStringLength res6:&nbsp;Int&nbsp;=&nbsp;4但如果我试着用它Foo包含其他东西,而不是String:scala>&nbsp;Foo(123).getStringLength<console>:9:&nbsp;error:&nbsp;could&nbsp;not&nbsp;find&nbsp;implicit&nbsp;value&nbsp;for&nbsp;parameter&nbsp;evidence:&nbsp;=:=[Int,String]您可以将该错误理解为“无法找到int=string的证据”.应该是这样的!getStringLength气势磅礴进一步限制关于…的类型A比什么Foo一般需要;也就是说,您只能调用getStringLength在.上Foo[String]..这个约束是在编译时强制执行的,这很酷!<:<和<%<工作方式类似,但略有变化:A =:= B意思是A一定就是BA <:< B表示A必须是B的子类型(类似于简约类型约束<:)A <%< B意思是A必须是可见作为B,可能通过隐式转换(类似于简单类型约束)。<%)这个片段很好地解释了这类事情过去是如何完成的,以及广义类型约束如何使它现在变得更容易。增编要回答你的后续问题,无可否认,我给出的例子是相当人为的,显然没有用。但是想象一下使用它来定义类似于List.sumInts方法,该方法将整数列表相加。您不希望在任何旧方法上调用此方法List,只是一个List[Int]..但是List类型构造函数不能受到如此的约束;您仍然希望能够有字符串、foos、条形图和诸如此类的列表。因此,通过在sumInts,你可以确保就是那种方法有一个附加约束,只能在List[Int]..实际上,你是在为某些类型的列表编写特例代码。

宝慕林4294392

不是一个完整的答案(其他人已经回答了这个问题),我只想指出以下几点,这可能有助于更好地理解语法:您通常使用这些“操作符”的方式,例如在Pelotom的示例中:def&nbsp;getStringLength(implicit&nbsp;evidence:&nbsp;A&nbsp;=:=&nbsp;String)利用Scala的选择类型运算符的infix语法.所以,A =:= String是相同的=:=[A, String](和=:=只是一个有着花哨名字的类别或特征)。请注意,这个语法也适用于“常规”类,例如,您可以编写:val&nbsp;a:&nbsp;Tuple2[Int,&nbsp;String]&nbsp;=&nbsp;(1,&nbsp;"one")就像这样:val&nbsp;a:&nbsp;Int&nbsp;Tuple2&nbsp;String&nbsp;=&nbsp;(1,&nbsp;"one")它类似于方法调用的两个语法,即“Normal”.和()以及运算符语法。

慕婉清6462132

阅读其他答案,了解这些构造是什么。这是什么时候你应该用它们。当只需要对特定类型的方法进行约束时,可以使用它们。下面是一个例子。假设您想定义一个同构对,如下所示:class&nbsp;Pair[T](val&nbsp;first:&nbsp;T,&nbsp;val&nbsp;second:&nbsp;T)现在要添加一个方法smaller,就像这样:def&nbsp;smaller&nbsp;=&nbsp;if&nbsp;(first&nbsp;<&nbsp;second)&nbsp;first&nbsp;else&nbsp;second只有在T是被命令的。您可以限制整个类:class&nbsp;Pair[T&nbsp;<:&nbsp;Ordered[T]](val&nbsp;first:&nbsp;T,&nbsp;val&nbsp;second:&nbsp;T)但这似乎是个耻辱-当T不是命令。使用类型约束,仍然可以定义smaller方法:def&nbsp;smaller(implicit&nbsp;ev:&nbsp;T&nbsp;<:<&nbsp;Ordered[T])&nbsp;=&nbsp;if&nbsp;(first&nbsp;<&nbsp;second)&nbsp;first&nbsp;else&nbsp;second实例化,比如说,Pair[File],&nbsp;只要你不打电话&nbsp;smaller在上面。如属Option,实现者希望orNull方法,尽管它没有意义Option[Int]..通过使用类型约束,一切都很好。你可以用orNull在.上Option[String],您可以形成一个Option[Int]使用它,只要你不打电话orNull在上面。如果你试着Some(42).orNull,你得到了迷人的信息&nbsp;error:&nbsp;Cannot&nbsp;prove&nbsp;that&nbsp;Null&nbsp;<:<&nbsp;Int
随时随地看视频慕课网APP
我要回答