类型化函数
所谓类型化函数,指的是在调用函数时可以指定参数的类型。Scala的类型化函数通过变量的使用提供了更大的灵活性。那么,如何定义一个泛型类型函数将指定其参数的类型?
下面我们将创建一个类型化函数,它将指定一个T类型的泛型参数,如下所示:
object demo {
// 应用折扣的泛型函数
def applyDiscount[T](discount: T) {
discount match {
case d: String =>
println(s"在数据库中查找 $d 的百分比折扣")
case d: Double =>
println(s"$d 折扣优惠")
case _ =>
println("不支持的折扣类型")
}
}
def main(args: Array[String]): Unit = {
// 要调用类型化函数applyDiscount(),必须提供其参数的类型。
applyDiscount[String]("COUPON_123")
applyDiscount[Double](10)
applyDiscount[Int](10)
}
}
执行上面的代码,输出内容如下:
在数据库中查找 COUPON_123 的百分比折扣
10.0 折扣优惠
不支持的折扣类型
虽然可以依赖Scala的类型推断来推断函数参数的类型,但一般来说,显式指定参数类型是一个很好的实践。
多态函数
多态函数指的是具有泛型返回类型的函数。在多态函数中,我们可以指定参数的类型以及函数的返回类型。
下面让我们定义另一个本质上是多态的函数。我们将函数命名为applyDiscountWithReturnType(),它将接受泛型类型T作为其折扣参数。但是它也会返回一个类型为T的Sequence。
object demo {
// 定义一个多态函数
// 它将接受泛型类型T作为其折扣参数。但是它也会返回一个类型为T的Sequence。
def applyDiscountWithReturnType[T](discount: T): Seq[T] = {
discount match {
case d: String =>
println(s"在数据库中查找 $d 的百分比折扣")
Seq[T](discount)
case d: Double =>
println(s"$d 折扣优惠")
Seq[T](discount)
case d @ _ =>
println("不支持的折扣类型")
Seq[T](discount)
}
}
def main(args: Array[String]): Unit = {
// 使用不同的类型,即String、Double和Char来分别调用多态函数
println(s"带String参数调用结果 = ${applyDiscountWithReturnType[String]("COUPON_123")}")
println()
println(s"带Double参数调用结果 = ${applyDiscountWithReturnType[Double](10.5)}")
println()
println(s"带Char参数调用结果 = ${applyDiscountWithReturnType[Char]('U')}")
}
}
执行以上代码,输出结果如下:
在数据库中查找 COUPON_123 的百分比折扣
带String参数调用结果 = List(COUPON_123)
10.5 折扣优惠
带Double参数调用结果 = List(10.5)
不支持的折扣类型
带Char参数调用结果 = List(U)
为简单起见,我们将为模式匹配中的每一种情况返回一个类型为T的新序列。对于调用多态函数applyDiscountWithReturnType()时使用的每个指定类型,该函数还返回相同类型的Sequence序列。
关于@运算符
@运算符允许将匹配的模式绑定到变量。请看下面的示例:
object demo {
def main(args: Array[String]): Unit = {
// 例如,考虑以下情况:
val o: Option[Int] = Some(2)
// 可以很容易地提取内容:
o match {
case Some(x) => println(x)
case None =>
}
// 但是,如果想要的不是Some的内容,而是Option本身呢?
// 这将通过以下方式实现:
o match {
case x @ Some(_) => println(x)
case None =>
}
}
}
执行上面的代码,输出结果如下:
2
Some(2)
注意,@ 可用于任何级别,而不仅仅是顶级的匹配。
符号函数
符号函数指的是仅使用符号而不是字母命名的函数。当必须创建特定于域的语言语法时,Scala的这个特性是一个很好的构建块。
定义名称为符号的函数本质上与定义任何其他函数相同。这个函数没有名称,而是用一些符号来定义。例如:
def -(discount: Double): Double = {
totalCost - discount
}
调用一个函数,其名称只是一个符号,就像上面步骤中的-函数一样,与调用任何其他函数没有什么不同。
println(s"调用函数 - = ${donutCostCalculator.-(10.5)}")
Scala允许使用如下所示的操作符样式来调用函数:
println(s"调用函数-使用操作符样式表示法 = ${donutCostCalculator - 10.5}")
使用操作符样式调用函数与调用函数没有太大区别,只是不需要指定点(.)。当调用函数名只是符号时,使用操作符风格更清晰。
既然已经知道了如何定义名称只是符号的函数,那么让我们创建另一个名为+++的函数。
def +++(taxAmount: Double): Double = {
totalCost + taxAmount
}
完整代码如下:
object demo {
val totalCost = 100
// 定义名称为符号的函数本质上与定义任何其他函数相同。这个函数没有名称,而是用一些符号来定义。例如:
def -(discount: Double): Double = {
totalCost - discount
}
// 既然已经知道了如何定义名称只是符号的函数,那么创建另一个名为+++的函数。
def +++(taxAmount: Double): Double = {
totalCost + taxAmount
}
def main(args: Array[String]): Unit = {
// 调用一个函数,其名称只是一个符号,就像上面步骤中的-函数一样,与调用任何其他函数没有什么不同。
println(s"调用函数 - = ${demo07.-(10.5)}")
// Scala允许使用如下所示的操作符样式来调用函数
// 使用操作符样式调用函数与调用函数没有太大区别,只是不需要指定点(.)。
// 当调用函数名只是符号时,使用操作符风格更清晰。
println(s"调用函数-使用操作符样式表示法 = ${demo07 - 10.5}")
// 加税计算的方法
println(s"调用+++函数 = ${demo07 +++ 13.5}")
}
}
执行以上代码,输出结果如下:
调用函数 - = 89.5
调用函数-使用操作符样式表示法 = 89.5
调用+++函数 = 113.5
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
暂无评论内容