当前位置: 首页 > news >正文

转载:浅谈 Scala 中下划线的用途

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

相关文章:

  • buildroot mysql mysql.mk hacking
  • 来介绍一个很好的工具--TodoList
  • Vuejs——(9)组件——props数据传递
  • struts技术的logic标签
  • Centos7下安装mysql5.6需要注意的点
  • 算法之美--3.2.3 KMP算法
  • log4j详解
  • angularjs data-ng-app 和ng-app的区别
  • 微软发布WF教程及大量示例
  • zabbix3.0.4-agent通过shell脚本获取mysql数据库登陆用户
  • 一个n的flex组件(SpringGraph Flex Component)
  • CString类常用方法(转载)
  • 网站产生流量的几个方法
  • 获取数据库内容二
  • 网页素材
  • 【刷算法】从上往下打印二叉树
  • axios请求、和返回数据拦截,统一请求报错提示_012
  • Java编程基础24——递归练习
  • Redux 中间件分析
  • 二维平面内的碰撞检测【一】
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 回流、重绘及其优化
  • 利用jquery编写加法运算验证码
  • 聊聊redis的数据结构的应用
  • 每天10道Java面试题,跟我走,offer有!
  • 实现菜单下拉伸展折叠效果demo
  • 思考 CSS 架构
  • 我的业余项目总结
  • 小程序button引导用户授权
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​io --- 处理流的核心工具​
  • ​linux启动进程的方式
  • #{} 和 ${}区别
  • #pragma multi_compile #pragma shader_feature
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (3)STL算法之搜索
  • (Oracle)SQL优化技巧(一):分页查询
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .net快速开发框架源码分享
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [20190401]关于semtimedop函数调用.txt
  • [2544]最短路 (两种算法)(HDU)
  • [AIGC] Java 和 Kotlin 的区别
  • [Android] Amazon 的 android 音视频开发文档
  • [BZOJ1053][HAOI2007]反素数ant
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [CTF]php is_numeric绕过