了解部分函数中的 'case' 关键字
Understand 'case' keyword in partial functions
我是 Scala 的新手,我正在尝试解码它的结构,我了解了 pattern matching 并且语法类似于 Java switch 语句
val x: Int = Random.nextInt(10)
x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "other"
}
此处的代码非常明显且可读。我遇到了 partial functions 非常明显并且很清楚它们是什么
A partial function is a function that does not provide an answer for
every possible input value it can be given.
我感到困惑的是在部分函数的主体中使用 case
像这样:
val divide2: PartialFunction[Int, Int] = {
case d: Int if d != 0 => 42 / d // WHAT IS THIS ?!
}
我不明白 case
是如何在没有 match
语句的情况下使用的,这是如何被 Scala 解释的,它是如何读取的,它是一个方法,一个 class或另一种构造?,还有哪些其他方法可以使用 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
}
这是如何工作的?
尝试这个会出错
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: ?
是否在部分函数之外的其他地方使用了不匹配的大小写?
这意味着只有当输入参数可以匹配 case 表达式时,才会应用偏函数。
实际生成的class是这样的:
val divide = new PartialFunction[Int, Int] {
def apply(x: Int) = 42 / x
def isDefinedAt(x: Int) = x != 0
}
使用 orElse 可以应用或处理多个定义:
funcForInt orElse funcForDouble orElse funcForString
构图不错?
编辑:
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
}
以上是使用匿名 class 功能。如果你删除变量的类型,你只是给它一个块表达式,其中包含一些编译器无法真正使用的 case 表达式。
我会尽量回答这个问题:
I don't understand how case is used without match statement, how does
this is interpreted by Scala, how it is read, is it a method, a class
or another construct ?
主要参考 this 文章,我将引用和解释。
这样做的原因:
val f: (Any) => String = {
case i: Int => "Int"
case d: Double => "Double"
case _ => "Other"
}
是编译器将其解释为匿名函数
当您创建 val 函数时,您真正使用此类代码所做的只是将变量名分配给匿名函数。
为了支持第一个陈述,Scala 编程的第 15.7 节指出:
A sequence of cases in curly braces can be used anywhere a function literal can be used.
所以它与在 filter
或 collect
.
中使用相同的语法并没有什么不同
上面的代码实质上创建了一个 Function1
对象。正如 this source 解释的那样:
The main distinction between PartialFunction and scala.Function1 is
that the user of a PartialFunction may choose to do something
different with input that is declared to be outside its domain.
它是一个模式匹配匿名函数,如 the specification 中所述。
Trying this gives an error
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
}
被翻译成
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
}
}
我是 Scala 的新手,我正在尝试解码它的结构,我了解了 pattern matching 并且语法类似于 Java switch 语句
val x: Int = Random.nextInt(10)
x match {
case 0 => "zero"
case 1 => "one"
case 2 => "two"
case _ => "other"
}
此处的代码非常明显且可读。我遇到了 partial functions 非常明显并且很清楚它们是什么
A partial function is a function that does not provide an answer for every possible input value it can be given.
我感到困惑的是在部分函数的主体中使用 case
像这样:
val divide2: PartialFunction[Int, Int] = {
case d: Int if d != 0 => 42 / d // WHAT IS THIS ?!
}
我不明白 case
是如何在没有 match
语句的情况下使用的,这是如何被 Scala 解释的,它是如何读取的,它是一个方法,一个 class或另一种构造?,还有哪些其他方法可以使用 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
}
这是如何工作的?
尝试这个会出错
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: ?
是否在部分函数之外的其他地方使用了不匹配的大小写?
这意味着只有当输入参数可以匹配 case 表达式时,才会应用偏函数。
实际生成的class是这样的:
val divide = new PartialFunction[Int, Int] {
def apply(x: Int) = 42 / x
def isDefinedAt(x: Int) = x != 0
}
使用 orElse 可以应用或处理多个定义:
funcForInt orElse funcForDouble orElse funcForString
构图不错?
编辑:
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
}
以上是使用匿名 class 功能。如果你删除变量的类型,你只是给它一个块表达式,其中包含一些编译器无法真正使用的 case 表达式。
我会尽量回答这个问题:
I don't understand how case is used without match statement, how does this is interpreted by Scala, how it is read, is it a method, a class or another construct ?
主要参考 this 文章,我将引用和解释。
这样做的原因:
val f: (Any) => String = {
case i: Int => "Int"
case d: Double => "Double"
case _ => "Other"
}
是编译器将其解释为匿名函数
当您创建 val 函数时,您真正使用此类代码所做的只是将变量名分配给匿名函数。
为了支持第一个陈述,Scala 编程的第 15.7 节指出:
A sequence of cases in curly braces can be used anywhere a function literal can be used.
所以它与在 filter
或 collect
.
上面的代码实质上创建了一个 Function1
对象。正如 this source 解释的那样:
The main distinction between PartialFunction and scala.Function1 is that the user of a PartialFunction may choose to do something different with input that is declared to be outside its domain.
它是一个模式匹配匿名函数,如 the specification 中所述。
Trying this gives an error
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
}
被翻译成
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
}
}