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", "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 + y
list.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. 小结
下划线在大部分的应用场景中是以语法糖的形式出现的,可以减少击键次数,并且代码显得更加简洁。但是对于不熟悉下划线的同学阅读起来稍显困难,希望通过本文能够帮你解决这个的困惑。
--------------------- 本文来自 CODE男孩 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_24084925/article/details/79041595?utm_source=copy
Scala下划线_使用的更多相关文章
- scala中的下划线_
1.作为“通配符”,类似Java中的*. 例如 import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理! 例如 val s = sum(1 to 5 ...
- Scala 神奇的下划线 _
引言 在 Scala 中,下划线 _ 有很多种用法,作为 Scala 初学者也经常被下划线 _ 搞得晕头转向,下面是对 Scala 中下划线 _ 使用的简单总结~ 导包时, 下划线 _ 表示引用多个方 ...
- scala下划线的用法
1.作为“通配符”,类似Java中的*.如import scala.math._2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 to 5:_*)就是 ...
- css命名为何不推荐使用下划线_
一直习惯了在命名CSS样式名时使用下划线“_”做为单词的分隔符,这也是在写JS时惯用的写法. 用过CSS hack的朋友应该知道,用下划线命名也是一种hack,如使用“_style”这样的命名,可以让 ...
- 修改 Pattern代码使 Java 正则表达式支持下划线 '_'
为什么 由于工作是做数据ETL的,很多时候会使用到正则对数据进行提取,但是java的正则中的groupname不支持'_',官方的文档中是这样的: Group name A capturing gro ...
- Python 私有变量中两个下划线 _ _item 与 一个下划线的区别 _item
python中没有常量的说法, 但是可以通过元组实现一个常量 在python的私有变量中, 存在两个下划线 _ _item 与一个下划线 _item 的区别 前面带两个下划线的私有变量: 只能在本类中 ...
- python中有两个下划线__的是内置方法,一个下划线_或者没有下划线的可能是属性,也可能是方法,也可能是类名
python中有两个下划线__的是内置方法,一个下划线_或者没有下划线的可能是属性,也可能是方法,也可能是类名,如果在类中定义的就是类的私有成员. >>> dir(__builtin ...
- 为什么我不建议在C#中用下划线_开头来表示私有字段
我在C#官方文档的使用属性里看到这种代码: public class Date { private int _month = 7; // Backing store public int Month ...
- scala下划线
作为函数的参数 一个匿名的函数传递给一个方法或者函数的时候,scala会尽量推断出参数类型.例如一个完整的匿名函数作为参数可以写为 scala> def compute(f: (Double)= ...
随机推荐
- 读书笔记 C# yield return与yield break执行顺序的浅析
yield return可一次返回一个元素,并保留当前在代码中的位置,下次调用当前迭代器函数时,将从该位置从新执行.也就是说执行了yield return的时候,迭代器函数就返回了一个元素给forea ...
- 下载python中package的简便方法
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple xxx
- DevExpress ASP.NET Bootstrap Controls v18.2新功能详解(一)
行业领先的.NET界面控件2018年第二次重大更新——DevExpress v18.2日前正式发布,本站将以连载的形式为大家介绍新版本新功能.本文将介绍了DevExpress ASP.NET Boot ...
- <Java><Multi-thread><Lock interface>
Overview 介绍java的lock interface. Motivation java拥有像synchronized这样的内置锁,那为什么还需要lock这样的外置锁呢? 首先,性能不是选择sy ...
- get 和post 请求的写法
get请求 import requests base_url = 'http://httpbin.org' # 定义请求所需的参数,参数之间以英文逗号隔开 param_data = {'} # 发送G ...
- Oracle中sysdba身份和dba角色区别
sysdba身份登陆可以打开,关闭数据库,创建SPFILE,对数据库进行恢复操作等,而这些是DBA角色无法实现的:sysdba 是系统权限,dba是用户对象权限: sysdba,是管理oracle实例 ...
- 团队作业8——敏捷冲刺博客合集(Beta阶段)
第一篇(冲刺前安排):https://www.cnblogs.com/Aragaki-Yui/p/9057951.html 第二篇(冲刺第一天):https://www.cnblogs.com/Ara ...
- myql update from 语句
(6)UPDATE 语句与 SELECT 语句中的 TOP 子句一起使用对来自表 authors 的前十个作者的 state 列进行更新 UPDATE authors SET state = 'ZZ' ...
- python第一天 计算机基础
计算机硬件组成 控制器: 运算器 存储器I/O设备 与运行程序有关的三大核心硬件 cpu,内存,硬盘 运行软件时,硬件的运作流程 1.软件最先存放于硬盘当中,软件的代码运行时会由硬盘读入内存 2.cp ...
- Fizz Buzz 问题
要求: 给你一个整数n. 从 1 到 n 按照下面的规则打印每个数: 如果这个数被3整除,打印fizz. 如果这个数被5整除,打印buzz. 如果这个数能同时被3和5整除,打印fizz buzz. 示 ...