您的当前位置:首页正文

Scala基础-下划线使用指南

2021-04-15 来源:个人技术集锦
Scala基础-下划线使⽤指南

下划线这个符号⼏乎贯穿了任何⼀本Scala编程书籍,并且在不同的场景下具有不同的含义,绕晕了不少初学者。正因如此,下划线这个特殊符号⽆形中增加Scala的⼊门难度。本⽂希望帮助初学者踏平这个⼩⼭坡。

1. ⽤于替换Java的等价语法

由于⼤部分的Java关键字在Scala中拥有了新的含义,所以⼀些基本的语法在Scala中稍有变化。

1.1 导⼊通配符

*在Scala中是合法的⽅法名,所以导⼊包时要使⽤_代替。

//Java

import java.util.*;//Scala

import java.util._

1.2 类成员默认值

Java中类成员可以不赋初始值,编译器会⾃动帮你设置⼀个合适的初始值:

class Foo{

//String类型的默认值为null String s;}

⽽在Scala中必须要显式指定,如果你⽐较懒,可以⽤_让编译器⾃动帮你设置初始值:

class Foo{

//String类型的默认值为null var s: String = _}

该语法只适⽤于类成员,⽽不适⽤于局部变量。

1.3 可变参数

Java声明可变参数如下:

public static void printArgs(String ... args){ for(Object elem: args){

System.out.println(elem + \" \"); }}

调⽤⽅法如下:

//传⼊两个参数printArgs(\"a\//也可以传⼊⼀个数组

printArgs(new String[]{\"a\

在Java中可以直接将数组传给printArgs⽅法,但是在Scala中,你必须要明确的告诉编译器,你是想将集合作为⼀个独⽴的参数传进去,还是想将集合的元素传进去。如果是后者则要借助下划线:

printArgs(List(\"a\

1.4 类型通配符

Java的泛型系统有⼀个通配符类型,例如List,任意的List类型都是List的⼦类型,如果我们想编写⼀个可以打印所有List类型元素的⽅法,可以如下声明:

public static void printList(List list){ for(Object elem: list){

System.out.println(elem + \" \"); }}

对应的Scala版本为:

def printList(list: List[_]): Unit ={

list.foreach(elem => println(elem + \" \"))}

2 模式匹配

2.1 默认匹配

str match{

case \"1\" => println(\"match 1\")

case _ => println(\"match default\")}

2.2 匹配集合元素

//匹配以0开头,长度为三的列表expr match {

case List(0, _, _) => println(\"found it\") case _ =>}

//匹配以0开头,长度任意的列表expr match {

case List(0, _*) => println(\"found it\") case _ =>}

//匹配元组元素expr match {

case (0, _) => println(\"found it\") case _ =>}

//将⾸元素赋值给head变量val List(head, _*) = List(\"a\")

3. Scala特有语法

3.1 访问Tuple元素

val t = (1, 2, 3)

println(t._1, t._2, t._3)

3.2 简写函数字⾯量(function literal)

如果函数的参数在函数体内只出现⼀次,则可以使⽤下划线代替:

val f1 = (_: Int) + (_: Int)//等价于

val f2 = (x: Int, y: Int) => x + ylist.foreach(println(_))//等价于

list.foreach(e => println(e))list.filter(_ > 0)//等价于

list.filter(x => x > 0)

3.3 定义⼀元操作符

在Scala中,操作符其实就是⽅法,例如1 + 1等价于1.+(1),利⽤下划线我们可以定义⾃⼰的左置操作符,例如Scala中的负数就是⽤左置操作符实现的:

-2

//等价于2.unary_-

3.4 定义赋值操作符

我们通过下划线实现赋值操作符,从⽽可以精确地控制赋值过程:

class Foo {

def name = { \"foo\" }

def name_=(str: String) { println(\"set name \" + str) }

val m = new Foo()

m.name = \"Foo\" //等价于: m.name_=(\"Foo\")

3.5 定义部分应⽤函数(partially applied function)

我们可以为某个函数只提供部分参数进⾏调⽤,返回的结果是⼀个新的函数,即部分应⽤函数。因为只提供了部分参数,所以部分应⽤函数也因此⽽得名。

def sum(a: Int, b: Int, c: Int) = a + b + cval b = sum(1, _: Int, 3)b: Int => Int = b(2) //6

3.6 将⽅法转换成函数

Scala中⽅法和函数是两个不同的概念,⽅法⽆法作为参数进⾏传递,也⽆法赋值给变量,但是函数是可以的。在Scala中,利⽤下划线可以将⽅法转换成函数:

//将println⽅法转换成函数,并赋值给pval p = println _ //p: (Any) => Unit

4. ⼩结

下划线在⼤部分的应⽤场景中是以语法糖的形式出现的,可以减少击键次数,并且代码显得更加简洁。但是对于不熟悉下划线的同学阅读起来稍显困难,希望通过本⽂能够帮你解决这个的困惑。本⽂成⽂仓促,如有遗漏,欢迎留⾔! 转载请注明作者: joymufeng

因篇幅问题不能全部显示,请点此查看更多更全内容