Ade*_*lin 1 scala pattern-matching partialfunction
我是Scala的新手,我正在尝试对其结构进行解码,我了解了模式匹配,并且语法类似于Java switch语句
val x: Int = Random.nextInt(10)
x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "other"
}
Run Code Online (Sandbox Code Playgroud)
这段代码非常明显并且可读。我遇到了很明显的部分函数,清楚了它们是什么
偏函数是一种不能为每个可能的输入值都提供答案的函数。
我感到困惑的是case在这样的部分函数的主体中使用:
val divide2: PartialFunction[Int, Int] = {
case d: Int if d != 0 => 42 / d // WHAT IS THIS ?!
}
Run Code Online (Sandbox Code Playgroud)
我不明白怎么case没有用match的语句,请问这是由Scala中,它是如何读取解释,它是一个方法,一个类或其他结构?我可以用什么其他的方法case,而不match声明
编辑:
我尝试过这种情况,但还是不明白。例如
val SomeFun: PartialFunction[Int, Int] = {
case d: Int if d != 0 => 1000 / d
case f: Int if f != 2 => 100 / f
case m: Int if m != 1 => 10 / m
}
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?
尝试这样做会出现错误
val SomeFun = {
case d: Int if d != 0 => 1000 / d
case f: Int if f != 2 => 100 / f
case m: Int if m != 1 => 10 / m
}
Error:(29, 17) missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
Run Code Online (Sandbox Code Playgroud)
在部分功能之外的其他任何地方是否使用了不匹配的情况?
这意味着仅当输入参数可以匹配大小写表达式时,才会应用部分函数。
实际生成的类是这样的:
val divide = new PartialFunction[Int, Int] {
def apply(x: Int) = 42 / x
def isDefinedAt(x: Int) = x != 0
}
Run Code Online (Sandbox Code Playgroud)
使用orElse,您可以应用或处理多个定义:
funcForInt orElse funcForDouble orElse funcForString
Run Code Online (Sandbox Code Playgroud)
不错的构图?
编辑:
val SomeFun: PartialFunction[Int, Int] = {
case d: Int if d != 0 => 1000 / d
case f: Int if f != 2 => 100 / f
case m: Int if m != 1 => 10 / m
}
Run Code Online (Sandbox Code Playgroud)
以上是使用匿名类的功能。如果删除变量的类型,则只是给它一个带有一些case表达式的块表达式,而这些case表达式是编译器无法真正使用的。
参考:https : //www.james-willett.com/scala-anonymous-classes
它是规范中描述的模式匹配匿名函数。
尝试这样做会出现错误
Run Code Online (Sandbox Code Playgroud)val SomeFun = ...
这是因为需要知道参数类型,就像“普通”匿名函数一样x => ...。不同之处在于,在模式匹配匿名函数中,没有地方可以直接指定参数类型(相当于(x: Int) => ...),因此必须有一个预期类型,例如val SomeFun: PartialFunction[Int, Int]或val SomeFun: Int => Int。
val SomeFun: PartialFunction[Int, Int] = {
case d: Int if d != 0 => 1000 / d
case f: Int if f != 2 => 100 / f
case m: Int if m != 1 => 10 / m
}
Run Code Online (Sandbox Code Playgroud)
被翻译成
val SomeFun: PartialFunction[Int, Int] = new PartialFunction[Int, Int] {
override def apply(x: Int) = x match {
case d: Int if d != 0 => 1000 / d
case f: Int if f != 2 => 100 / f
case m: Int if m != 1 => 10 / m
}
override def isDefined(x: Int) = x match {
case d: Int if d != 0 => true
case f: Int if f != 2 => true
case m: Int if m != 1 => true
case _ => false
}
}
Run Code Online (Sandbox Code Playgroud)
我将尝试回答这个问题:
\n\n\n\n\n我不明白如何在没有匹配语句的情况下使用 case,Scala 如何解释它,如何读取它,它是方法、类还是其他构造?
\n
主要参考这篇文章,我将引用并解释该文章。
\n\n这样做的原因:
\n\nval f: (Any) => String = {\n case i: Int => "Int"\n case d: Double => "Double"\n case _ => "Other"\n}\nRun Code Online (Sandbox Code Playgroud)\n\n是编译器将其解释为匿名函数。
\n\n当您创建val函数时,您\xe2\x80\x99真正使用这样的代码所做的就是将变量名分配给匿名函数。
\n\n为了支持第一个陈述,《Scala 编程》第 15.7 节指出:
\n\n\n\n\n花括号中的一系列 case 可以用在可以使用函数文字的任何地方。
\n
filter因此,它与在 inside或中使用相同的语法并没有真正的不同collect。
上面的代码本质上创建了一个Function1对象。正如该消息来源所解释的:
\n\nPartialFunction 和 scala.Function1 之间的主要区别是 PartialFunction 的用户可以选择对声明为在其域之外的输入执行不同的操作。
\n