博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
转载:浅谈 Scala 中下划线的用途
阅读量:6424 次
发布时间:2019-06-23

本文共 3410 字,大约阅读时间需要 11 分钟。

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

1、存在性类型:Existential typesdef 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 valuefoo(_)              // 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?

[2] Scala punctuation (AKA symbols and operators)

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

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

[5] Scala简明教程

 

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

你可能感兴趣的文章
算法入门经典大赛 Dynamic Programming
查看>>
TortoiseGit:记住用户名和密码
查看>>
数据库的检索语句
查看>>
cocos2d-x3.0 实现HTTP请求GET、POST
查看>>
Iptables DDOS/CC 自动屏蔽脚本
查看>>
WPF VLC客户端和SDK的简单应用
查看>>
mysql函数之三:find_in_set() 函数 返回str在字符串集strlist中的序号
查看>>
js或者cs代码拼接html
查看>>
应用系统如何分析和获取SQL语句的执行代码
查看>>
拿年终奖前跳槽,你才是赢家!
查看>>
Mouse Key Hook
查看>>
MySQL占用内存过大的问题解决
查看>>
[Android] 转移“植物大战僵尸2”存档的办法,无需root
查看>>
【Xamarin挖墙脚系列:Xamarin开发环境配置需求】
查看>>
hdu5086——Revenge of Segment Tree
查看>>
8个经过证实的方法:提高机器学习模型的准确率
查看>>
C#中的文件同步
查看>>
libevent的使用(socket)
查看>>
Hadoop 的常用组件一览
查看>>
MongoDB安装、CURD增改查删操作、应用场景
查看>>