当前位置:首页 > 技术 > 正文内容

Scala 中下划线的神奇用法

访客 技术 2026年6月1日 1

我几天前开始学习Scala。最初,我对Scala中大量使用符号感到困惑。特别是_在不同的场景下有不同的含义,让我一头雾水。经过几天的研究(其实就是各种搜索),我逐渐理解了它的用法,甚至开始喜欢这种语法。好了,让我们来看看Scala中_的各种用法。

"提示" : "我是一个Scala新手"

模式匹配

在Scala中,模式匹配与Java的switch语句有些相似,但功能更强大。

def matchTest(x: Int): String = x match {
    case 1 => "一"
    case 2 => "二"
    case _ => "除了一和二之外的其他值"
  }

在Scala中,每个选择器会按照代码中出现的顺序与模式进行匹配,第一个匹配成功的分支会被执行。_在这里充当通配符,可以匹配任何值。Scala支持嵌套模式,所以_也可以嵌套使用。让我们再看一个在嵌套模式中使用_的例子。

expr match {
  case List(1,_,_) => "包含三个元素的列表,第一个元素是1"
  case List(_*)  => "包含零个或多个元素的列表"
  case Map[_,_] => "匹配任意键类型和任意值类型的映射"
  case _ =>
  }

匿名函数

Scala使用优雅的语法来表示匿名函数。_在匿名函数中充当参数的占位符。_只能使用一次,但我们可以使用多个下划线来引用不同的参数。

List(1,2,3,4,5).foreach(print(_))
List(1,2,3,4,5).foreach( a => print(a))

这里的_代表参数。第一种写法是第二种写法的简写形式。让我们再看一个接受两个参数的例子。

val total = List(10,20,30,40,50).reduceLeft(_+_)
val total = List(10,20,30,40,50).reduceLeft((a, b) => a + b)

有一篇很好的文章详细解释了上面这个例子的内部原理。

import导入语句

在Scala中,_在导入包时的作用类似于Java中的*

// 导入matching包中的所有类
import scala.util.matching._
// 导入Fun对象的所有成员(类似于Java中的静态导入)
import com.example.Fun._
// 导入Fun对象的所有成员,但将Foo重命名为Bar
import com.example.Fun.{ Foo => Bar , _ }
// 导入Fun对象的所有成员,除了Foo。要排除某个成员,可以将其重命名為_
import com.example.Fun.{ Foo => _ , _ }

属性

在Scala中,所有非私有的var都会自动生成getter和setter方法。getter方法名与变量名相同,setter方法名则是变量名加上_=。我们也可以自定义getter和setter。这看起来与Ruby的getter和setter很相似。好,让我们来看一个使用getter和setter的例子。

class Person {
   private var _age = 0
   def age: Int = _age
   def age_=(n: Int): Unit = {
      require(n > 0, "年龄必须为正数")
      _age = n
   }
}
val person = new Person
person.age = 25
println(person.age)

函数

Scala是一门函数式语言,因此我们可以像处理普通变量一样处理函数。如果你想把一个函数赋值给一个新变量,函数会被立即调用,其结果会被赋值给这个变量。这种困惑源于方法调用时可选的花括号。我们需要在函数名后面加上_才能将其赋值给另一个变量。

class Demo {
  def calculate = {
    // 一些代码
  }
  val calculateRef = calculate _
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。