Scala下划线“_”的常用用法大全

本来想自己总结一篇博客,

在网上搜了一下,发现这篇不错遂转载以记之

在Scala中,我们随处可见下划线“_”,本篇博客记录了Scala中下划线“_”的各种常用用法,可能不是全部的用法。

目录

一、集合和函数中使用

1.1 集合

1.2 函数

二、作为通配符

2.1 import语句

2.2 case语句

2.3 元组(tuple)

三、下划线和其他符号组合的使用方式

3.1 下划线与星号(_*)

3.1.1 变长参数

3.1.2 变量声明中的模式

3.2 下划线与等号(_=)

四、方法转化为函数

五、作为标识符

5.1 初始化变量

参考文献

一、集合和函数中使用
1.1 集合

scala> val newArry= (1 to 10).map(_*2)
newArry: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
 
scala> println(newArry)
Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)


这里的下划线代表了集合中的“某(this)”一个元素。这个用法很常见,在foreach等语句中也可以使用。

1.2 函数

scala> def setFunction(parm1:Double,parm2:Double): Double = parm1+parm2
setFunction: (parm1: Double, parm2: Double)Double
 
scala> val set=setFunction(3.0,_:Double)
set: Double => Double = <function1>
 
scala> println(set(7.1))
10.1
 
scala> val set=setFunction(_:Double,_:Double)
set: (Double, Double) => Double = <function2>
 
scala> println(set(7.1, 3.0))
10.1


这是Scala特有的“偏函数”用法。

二、作为通配符
2.1 import语句
这里的math._就相当于Java中的math.*; 即“引用包中的所有内容”。

import math._


2.2 case语句
这里的下划线相当于“others”的意思,就像Java  switch语句中的“default”。

scala> var value1="a"
value1: String = a
 
scala> var result=  value1 match{
     |        case "a" => 1
     |        case "b" => 2
     |        case _ =>"result"
     |  }
result: Any = 1
 
scala> println(result)
1
 
scala> var value2="c"
value2: String = c
 
scala> var result=  value2 match{
     |        case "a" => 1
     |        case "b" => 2
     |        case _ =>"result"
     |  }
result: Any = result
 
scala> println(result)
result


2.3 元组(tuple)

scala> val value=(1,2)
value: (Int, Int) = (1,2)
 
scala> print(value._1)
1
scala> print(value._2)
2


可以通过模式匹配获取元组的元素,当不需要某个值的时候可以使用_替代,例如

scala> val t = (1, 3.14, "Fred")
t: (Int, Double, String) = (1,3.14,Fred)
 
scala> val (first, second, _) = t
first: Int = 1
second: Double = 3.14
 
scala> val (first, _, _) = t
first: Int = 1


 
三、下划线和其他符号组合的使用方式
3.1 下划线与星号(_*)
3.1.1 变长参数
例如定义一个变长参数的方法sum,然后计算1-5的和,可以写为

scala> def sum(args: Int*) = {
     | var result = 0
     | for (arg <- args) result += arg
     | result
     | }
sum: (args: Int*)Int
 
scala> val s = sum(1,2,3,4,5)
s: Int = 15
 


但是如果使用这种方式就会报错

scala> val s = sum(1 to 5)
<console>:12: error: type mismatch;
 found   : scala.collection.immutable.Range.Inclusive
 required: Int
       val s = sum(1 to 5)
                     ^


这种情况必须在后面写上: _*将1 to 5转化为参数序列

scala> val s = sum(1 to 5: _*)
s: Int = 15


3.1.2 变量声明中的模式
例如,下面代码分别将arr中的第一个和第二个值赋给first和second

scala> val arr = Array(1,2,3,4,5)
arr: Array[Int] = Array(1, 2, 3, 4, 5)
 
scala> val Array(1, 2, _*) = arr
 
scala> val Array(first, second, _*) = arr
first: Int = 1
second: Int = 2


 
3.2 下划线与等号(_=)
我们先看一段代码:

abstract class Person {
    def id: Int  
}
class Student extends Person{
    override var id = 9527  //Error: method id_= overrides nothing
}


 
在scala中定义了一个var变量,会自动生成getter和setter方法。
那么如果父类中只定义了一个方法def id: Int,用来生成用户的id,而子类用var变量重写这个方法的话override var id = 9527,编译会报错method id_=overrides nothing,从报错中可以看出来,由于scala会为var变量自动生成了一个setter方法(id_),但是父类并没有这个方法,所以是无法重写的。

abstract class Person {
    def id: Int  
    def id_=(value: Int) //父类必须有set方法
}
class Student extends Person{
    override var id = 9527 //为var变量自动生成get和set方法
}
 


所以,用var重写父类中的def只有上述的这一种情况才可以。

四、方法转化为函数
在Scala中方法不是值,而函数是。所以一个方法不能赋值给一个val变量,而函数可以。

scala> def increment(n: Int) = n + 1
increment: (n: Int)Int
 
scala> val fun = increment
<console>:12: error: missing argument list for method increment
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `increment _` or `increment(_)` instead of `increment`.
       val fun = increment


在这个例子中定义了一个方法increment,然后将这个方法赋值给变量fun失败。根据提示,可以通过将方法转化为函数的方式实现。

scala> val fun = increment _
fun: Int => Int = <function1>
 
scala> fun(1)
res30: Int = 2


关于scala里方法和函数的区别,请参考《Scala中Method方法和Function函数的区别》

五、作为标识符
5.1 初始化变量
name声明为null,例:var name:String=null。这里的下划线和null的作用是一样的。

var name:String=_
name: String = null
 
scala> name="hello world"
name: String = hello world
 
scala> println(name)
hello world

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值