2019独角兽企业重金招聘Python工程师标准>>>

欢迎访问PlayScala社区(http://www.playscala.cn)

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

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

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

1.1 导入通配符

*在Scala中是合法的方法名,所以导入包时要使用_代替。

//Java
import java.util.*;//Scala
import java.util._

1.2 类成员默认值

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

class Foo{//String类型的默认值为nullString s;
}

而在Scala中必须要显式指定,如果你比较懒,可以用_让编译器自动帮你设置初始值:

class Foo{//String类型的默认值为nullvar s: String = _
}

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

1.3 可变参数

Java声明可变参数如下:

public static void printArgs(String ... args){for(Object elem: args){System.out.println(elem + " ");}
}

调用方法如下:

 //传入两个参数
printArgs("a", "b");
//也可以传入一个数组
printArgs(new String[]{"a", "b"});

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

printArgs(List("a", "b"): _*)

1.4 类型通配符

Java的泛型系统有一个通配符类型,例如List<?>,任意的List<T>类型都是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 + c
val b = sum(1, _: Int, 3)
b: Int => Int = <function1>
b(2) //6

3.6 将方法转换成函数

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

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

4. 小结

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

转载于:https://my.oschina.net/joymufeng/blog/863823

Scala基础 - 下划线使用指南相关推荐

  1. element-ui tabs标签嵌套使用时 基础下划线不显示的问题

    前几天写到 tabs标签 嵌套使用的时候,嵌套的tabs 下划线无法显示,记录下解决办法 在内层tabs 上添加v-if ="外层tabs的activeName",意思为当选中这个 ...

  2. css点击a标签显示下划线_好程序员HTML5培训教程-html和css基础知识

    好程序员HTML5培训教程-html和css基础知识,Html是超文本标记语言(英语全称:HyperText Markup Language,简称:HTML)是一种用于创建网页的标准标记语言. Css ...

  3. 【Python基础】关于Python的前后、单双下划线作用

    python的各种下划线 在Python中,可能最常见的就是各种常量.变量.函数.方法前后添加的那些下划线了.有前面加的.后面加的,加一个的,加两个的,看到头晕.那么,你对这些知识都掌握了吗 ?让我们 ...

  4. 27、Python 面向对象(创建类、创建实例对象、访问属性、内置类属性、对象销毁、类的继承、方法重写、基础重载方法、运算符重载、类属性与方法、下划线双下划线)

    27Python面向对象(Python2) Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的.本章节我们将详细介绍Python的面向对象编程. ...

  5. scala中何时使用下划线_在Scala中使用下划线

    scala中何时使用下划线 Underscore (_) character is reserved in Scala and has multiple usages in the programmi ...

  6. C语言中的标识符以字母或下划线开头,牛逼大神整理的C语言基础知识,你确定你不码下来?...

    [[怪兽爱C语言]牛逼大神整理的C语言基础知识,你确定你不码下来?]https://toutiao.com/group/6577344220355363341/?iid=15906422033& ...

  7. scala下划线的用法

    1.作为"通配符",类似Java中的*.如import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 ...

  8. element tabs 的基础类型下划线不显示

    tabs 的基础类型用在多层嵌套里面导致下划线不显示,排除出style的width为0没有赋值到: 解决方法是用v-if来重新加载.

  9. python3-xlwt-Excel设置表格基础(字体颜色 背景颜色 设置边框 边框颜色 冻结窗口 字体大小 字体高度 字体加粗 下划线 斜体字 单元格对齐方式 自动换行 删除线 超链接 插入公式)

    文章目录 引入xlwt和创建workboos对象 初始化样式和创建设置字体,赋值给style 保存文件 自定义样式 字体颜色 背景颜色 设置边框 边框颜色 冻结窗口 字体大小 字体高度 字体加粗 下划 ...

最新文章

  1. PHP自动搜索框post,php搜索框提示(自动完成)实例代码_PHP教程
  2. layui搭配Distpicker实现省市县多级联动
  3. 参会邀请 - CCKS2020 | 2020全国知识图谱与语义计算大会(CCKS2020)明日开幕
  4. 怎样格式化电脑_硬盘数据销毁最安全的步骤是怎样的?有公司可以做吗
  5. 小米MIX 4屏幕规格曝光:华星光电1080P面板 或支持屏下摄像
  6. pandas 删除行
  7. OpenCV图像处理(17)—— 各种二值化对比
  8. Codeblocks中的empty project和console application
  9. 5.1.3 5GMM sublayer states
  10. 串口(UART)的FPGA实现(含源码工程)
  11. Win11如何设置系统还原点?
  12. ionic ActionSheet(上拉菜单)
  13. MES生产计划排程:提升工厂效益的有力工具
  14. 文件上传,搞懂这8种场景就够了
  15. QT提取字符串中的数字
  16. (附源码)ssm校园交流网站 毕业设计 261624
  17. 算力狂热时代的冷静之道:宁畅总裁秦晓宁分享企业的算力最优解
  18. 笔记本nc10装linux,三星nc10笔记本如何设置U盘启动
  19. EditText的getText()方法
  20. 致远项目管理SPM系统核心价值

热门文章

  1. hadoop2.4.1+hbase0.98.3实现的分布式网盘系统初步(已开源)
  2. Sublime Text 2 中怎样查找scope的名称
  3. Android从零开始(十一)
  4. 配置整合DWR3.0和Spring2.5使用annotation注解
  5. hdu 5020 求三点共线的组合数(容器记录斜率出现次数)
  6. 【Groovy】MOP 元对象协议与元编程 ( Expando 动态类 | 创建动态类 | 为动态类增加字段和方法 )
  7. 【Java 并发编程】线程简介 ( 进程与线程 | 并发概念 | 线程间通信 | Java 并发 3 特性 )
  8. 【计算理论】计算复杂性 ( 小 O 记号 | 严格渐进上界 | 分析算法的时间复杂度 )
  9. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 完整代码示例 | 申请权限 | 申请权限原理对话框 | 引导用户手动设置权限对话框 )
  10. 【Android NDK 开发】JNI 方法解析 ( C/C++ 调用 Java 方法 | 函数签名 | 调用对象方法 | 调用静态方法 )