Scala 作为一门函数式编程语言,对习惯了指令式编程语言的同学来说,会不大习惯,这里除了思维方式之外,还有语法层面的,比如 underscore(下划线)就会出现在多种场合,令初学者相当疑惑,今天就来总结下 Scala 中下划线的用法。

1、存在性类型:Existential types
def foo(l: List[Option[_]]) = ...

2、高阶类型参数:Higher kinded type parameters
case class A[K[_],T](a: K[T])

3、临时变量:Ignored variables
val _ = 5

4、临时参数:Ignored parameters
List(1, 2, 3) foreach { _ => println("Hi") }

5、通配模式:Wildcard patterns
Some(5) match { case Some(_) => println("Yes") }
match {
     case List(1,_,_) => " a list with three element and the first element is 1"
     case List(_*)  => " a list with zero or more elements "
     case Map[_,_] => " matches a map with any key type and any value type "
     case _ =>
 }
val (a, _) = (1, 2)
for (_ <- 1 to 10)

6、通配导入:Wildcard imports
import java.util._

7、隐藏导入:Hiding imports
// Imports all the members of the object Fun but renames Foo to Bar
import com.test.Fun.{ Foo => Bar , _ }

// Imports all the members except Foo. To exclude a member rename it to _
import com.test.Fun.{ Foo => _ , _ }

8、连接字母和标点符号:Joining letters to punctuation
def bang_!(x: Int) = 5

9、占位符语法:Placeholder syntax
List(1, 2, 3) map (_ + 2)
_ + _   
( (_: Int) + (_: Int) )(2,3)

val nums = List(1,2,3,4,5,6,7,8,9,10)

nums map (_ + 2)
nums sortWith(_>_)
nums filter (_ % 2 == 0)
nums reduceLeft(_+_)
nums reduce (_ + _)
nums reduceLeft(_ max _)
nums.exists(_ > 5)
nums.takeWhile(_ < 8)

10、偏应用函数:Partially applied functions
def fun = {
    // Some code
}
val funLike = fun _

List(1, 2, 3) foreach println _

1 to 5 map (10 * _)

//List("foo", "bar", "baz").map(_.toUpperCase())
List("foo", "bar", "baz").map(n => n.toUpperCase())
******·····用于将方法转换成函数,比如val f=sqrt _,以后直接调用f(250)就能求平方根了

11、初始化默认值:default value
var i: Int = _

12、作为参数名:
//访问map
var m3 = Map((1,100), (2,200))
for(e<-m3) println(e._1 + ": " + e._2)
m3 filter (e=>e._1>1)
m3 filterKeys (_>1)
m3.map(e=>(e._1*10, e._2))
m3 map (e=>e._2)

//访问元组:tuple getters
(1,2)._2

13、参数序列:parameters Sequence 
_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理。例如val s = sum(1 to 5:_*)就是将1 to 5当作参数序列处理。
//Range转换为List
List(1 to 5:_*)

//Range转换为Vector
Vector(1 to 5: _*)

//可变参数中
def capitalizeAll(args: String*) = {
  args.map { arg =>
    arg.capitalize
  }
}

val arr = Array("what's", "up", "doc?")
capitalizeAll(arr: _*)

这里需要注意的是,以下两种写法实现的是完全不一样的功能:

foo _               // Eta expansion of method into method value

foo(_)              // Partial function application

Example showing why foo(_) and foo _ are different:

trait PlaceholderExample {
  def process[A](f: A => Unit)

  val set: Set[_ => Unit]

  set.foreach(process _) // Error 
  set.foreach(process(_)) // No Error
}

In the first case, process _ represents a method; Scala takes the polymorphic method and attempts to make it monomorphic by filling in the type parameter, but realizes that there is no type that can be filled in for A that will give the type (_ => Unit) => ? (Existential _ is not a type).

In the second case, process(_) is a lambda; when writing a lambda with no explicit argument type, Scala infers the type from the argument that foreach expects, and _ => Unit is a type (whereas just plain _ isn't), so it can be substituted and inferred.

This may well be the trickiest gotcha in Scala I have ever encountered.

Refer:

[1] What are all the uses of an underscore in Scala?

http://stackoverflow.com/questions/8000903/what-are-all-the-uses-of-an-underscore-in-scala

[2] Scala punctuation (AKA symbols and operators)

http://stackoverflow.com/questions/7888944/scala-punctuation-aka-symbols-and-operators/7890032#7890032

[3] Scala中的下划线到底有多少种应用场景?

http://www.zhihu.com/question/21622725

[4] Strange type mismatch when using member access instead of extractor

http://stackoverflow.com/questions/9610736/strange-type-mismatch-when-using-member-access-instead-of-extractor/9610961

[5] Scala简明教程

http://colobu.com/2015/01/14/Scala-Quick-Start-for-Java-Programmers/

转载自https://my.oschina.NET/leejun2005/blog/405305

转载:浅谈 Scala 中下划线的用途的更多相关文章

  1. 浅谈 Scala 中下划线的用途

    Scala 作为一门函数式编程语言,对习惯了指令式编程语言的同学来说,会不大习惯,这里除了思维方式之外,还有语法层面的,比如 underscore(下划线)就会出现在多种场合,令初学者相当疑惑,今天就 ...

  2. Scala 中下划线的用途

    转载自:https://my.oschina.net/leejun2005/blog/405305 Scala 作为一门函数式编程语言,对习惯了指令式编程语言的同学来说,会不大习惯,这里除了思维方式之 ...

  3. 转载-浅谈Ddos攻击攻击与防御

    EMail: jianxin#80sec.comSite: http://www.80sec.comDate: 2011-2-10From: http://www.80sec.com/ [ 目录 ]一 ...

  4. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

  5. <转载>浅谈C/C++的浮点数在内存中的存储方式

    C/C++浮点数在内存中的存储方式 任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100.则在Intel CPU架构的系统中 ...

  6. 转载--浅谈spring4泛型依赖注入

    转载自某SDN-4O4NotFound Spring 4.0版本中更新了很多新功能,其中比较重要的一个就是对带泛型的Bean进行依赖注入的支持.Spring4的这个改动使得代码可以利用泛型进行进一步的 ...

  7. Scala 中下划线的用法

    1.存在性类型:Existential types def foo(l: List[Option[_]]) = ... 2.高阶类型参数:Higher kinded type parametersca ...

  8. (转载) 浅谈python编码处理

    最近业务中需要用 Python 写一些脚本.尽管脚本的交互只是命令行 + 日志输出,但是为了让界面友好些,我还是决定用中文输出日志信息. 很快,我就遇到了异常: UnicodeEncodeError: ...

  9. [转载]浅谈组策略设置IE受信任站点

    在企业中,通常会有一些业务系统,要求必须加入到客户端IE受信任站点,才能完全正常运行访问,在没有域的情况下,可能要通过管理员手动设置,或者通过其它网络推送方法来设置. 有了域之后,这项工作就可以很好的 ...

随机推荐

  1. android_双击退出

    /** * 设置高速双击退出程序 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-g ...

  2. Spring Date JPA 更新部分字段

    在Spring Data JPA 中,新增和更新操作都是用save()的方式进行,JPA是通过什么方法来知道我们是要进行insert还是update呢? 经过测试,JPA对程序调用的save()方法判 ...

  3. 新鲜:阿里云的DataV数据可视化技术可以用起来

    直接通过拖拽+关联的方式就可以比较方便的做出下面这种大屏展示数据的界面   只要阿里云上购买DataV数据可视化套件(https://data.aliyun.com/experience/case8? ...

  4. 【ZH奶酪】为什么Python不需要函数重载?

    函数重载的作用是什么? 函数重载主要是为了解决两个问题 可变参数类型 可变参数个数 另外,一个基本的设计原则是,仅仅当两个函数除了参数类型和参数个数不同以外,其功能是完全相同的,此时才使用函数重载,如 ...

  5. SoapUI Pro Project Solution Collection-XML assert

    in soapui the XML object used here is from  org.w3c.dom package so you need to read this article car ...

  6. redis 频率限制

    方式1: $redis = new Redis(); //以自然时间控制 一自然分钟内超过100次进行限制, 屏蔽多久的时间必须为计数key时间的倍数 $key = 'xxxx'.date('Y-m- ...

  7. List stream 对象 属性去重

    单值去重不写了,记录对象去重 随手一个对象: @Data @AllArgsConstructor public class Milk { private Integer key; private St ...

  8. JDK自带jvisualvm监控工具

    定位 工具位于jdk\bin目录下(双击运行): 可以本地或者远程调试,本地调试会自动加载,远程调试需要配置.下面以Tomcat为例. 概述 监视 线程 抽样器 Java 堆 百度经验参考:https ...

  9. HDU 3277 Marriage Match III(并查集+二分答案+最大流SAP)拆点,经典

    Marriage Match III Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  10. layui table 根据条件改变更换表格颜色 高亮显示 数据筛选

    请问想让当layui表格的某个字段符合某个条件的时候,让该行变颜色.这样可以实现么. layui数据表格怎么更换表格颜色 layui表格 通过判断某一行中的某一列的值进行设置这一行的颜色 LayUI之 ...