Scala可变长度参数和:_*使用

本文介绍Scala中可变长度参数的使用,包括如何定义接收多个参数的函数,以及如何正确传递数组参数。同时,文章还探讨了下划线在Scala中的多种用途,如通配符、参数序列处理、集合元素指代等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 可变长度参数

cala 允许你指明函数的最后一个参数可以是重复的。这可以允许客户向函数传入可变长度参数列表。想要标注一个重复参数,在参数的类型之后放一个星号。

scala> def echo(args: String*) =
for (arg <- args) println(arg)
echo: (String*)Unit

这样定义, echo 可以被零个至多个 String 参数调用:

scala> echo()
scala> echo("one")
one
scala> echo("hello", "world!")
hello
world!

函数内部,重复参数的类型是声明参数类型的数组。因此, echo 函数里被声明为类型“ String* ”
的 args 的类型实际上是 Array[String] 。然而,如果你有一个合适类型的数组,并尝试把它当作
重复参数传入,你会得到一个编译器错误:

scala> val arr = Array("What's", "up", "doc?")
arr: Array[java.lang.String] = Array(What's, up, doc?)
scala> echo(arr)
<console>:7: error: type mismatch;

found : Array[java.lang.String]
required: String
echo(arr)

要实现这个做法,你需要在数组参数后添加一个冒号和一个 _* 符号,像这样:

scala> echo(arr: _*)
What's
up
doc?

这个标注告诉编译器把 arr 的每个元素当作参数,而不是当作单一的参数传给 echo 。

def sum(args: Int*):Int={
var total:Int=0
for (arg <- args) {
   total=total+arg
  }
  total
}

val s = sum(1 to 5:_*)

2. 下划线的用法

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

  1. 作为“通配符”,类似Java中的*。如import scala.math._
  2. :_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = sum(1 to 5:_*)就是将1 to 5当作参数序列处理。
  3. 指代一个集合中的每个元素。
  4. 在元组中,可以用方法_1, _2, _3访问组员。如a._2。其中句点可以用空格替代。
  5. 使用模式匹配可以用来获取元组的组员
  6. 还有一点,下划线_代表的是某一类型的默认值。

    对于Int来说,它是0。
    对于Double来说,它是0.0
    对于引用类型,它是null。


转自:https://blog.youkuaiyun.com/m0_37692438/article/details/71171732
以下是整合了单例对象讲解的完整博客内容: # Scala实现手机号码类型识别:从C语言基础到实战 作为学过C语言的零基础学习者,我们来看看Scala中如何实现手机号码类型识别。本文会结合C语言基础,对比介绍Scala的数组、函数与单例对象语法,再完成功能实现。 ## 一、Scala数组基础(对比C语言) 在C语言中,数组是固定长度、同类型元素的集合,比如 `int arr[5];`。而Scala的数组: - **可变特性**:默认创建后元素不可变(修改需重新赋值)。 - **定义方式**:通过 `Array` 类创建。 示例: ```scala // C语言数组定义 // int cArray[3] = {1, 2, 3}; // Scala数组定义 val scalaArray = Array(1, 2, 3) // 自动推断类型为Array[Int] ``` ## 二、Scala函数定义语法(对比C语言) C语言中,函数定义会声明返回值类型,如 `void func() { ... }` 表示无返回值。Scala函数语法更明确: - **`def` 关键字**Scala用 `def` 定义函数。 - **返回类型声明**Scala强制显式声明返回类型(少数递归场景除外)。无有意义返回值时,用 `Unit`(类似C语言的 `void`)。 - **函数定义结构**: ```scala def 函数名(参数: 参数类型): 返回类型 = { // 函数体 } ``` 例如: ```scala def identify(segment: String): Unit = { // 函数体逻辑,无实际返回值,用Unit } ``` ## 三、Scala单例对象(对比C语言全局函数) 在C语言中,全局函数可直接调用(如 `printf`)。Scala通过 **单例对象** 实现类似功能,但更强调封装性: - **`object` 关键字**:定义全局唯一的单例对象,无需实例化,直接通过名称访问成员。 - **程序入口**Scala程序的入口 `main` 方法必须定义在单例对象中。 示例: ```scala object PhoneNumberIdentify { // 单例对象内的方法可直接调用 def identify(segment: String): Unit = { println("识别逻辑") } // 程序入口,Scala程序从main方法启动 def main(args: Array[String]): Unit = { identify("133") // 直接调用单例对象内的方法 } } ``` **与C语言的对比**: - C语言的全局函数可直接调用(如 `func()`),Scala通过单例对象的名称调用(如 `PhoneNumberIdentify.identify("133")`)。 - 若方法定义在单例对象内部(与 `main` 平级),可省略对象名直接调用(如示例中的 `identify("133")`)。 ## 四、手机号码类型识别实现 ### 1. 准备号段数组 ```scala val telecomSegments = Array("133", "153", "177") val mobileSegments = Array("134", "135", "136") val unicomSegments = Array("130", "131", "132") ``` ### 2. 定义识别函数(在单例对象内) ```scala def identify(segment: String): Unit = { if (telecomSegments.contains(segment)) { println("中国电信") } else if (mobileSegments.contains(segment)) { println("中国移动") } else if (unicomSegments.contains(segment)) { println("中国联通") } else { println("暂不支持") } } ``` ### 3. 主方法调用 ```scala def main(args: Array[String]): Unit = { identify("133") // 直接调用单例对象内的方法 } ``` ## 五、代码完整示例 ```scala object PhoneNumberIdentify { // 定义各运营商号段数组 val telecomSegments = Array("133", "153", "177") val mobileSegments = Array("134", "135", "136") val unicomSegments = Array("130", "131", "132") // 定义识别函数(与main平级) def identify(segment: String): Unit = { if (telecomSegments.contains(segment)) { println("这个号码是属于中国电信的") } else if (mobileSegments.contains(segment)) { println("这个号码是属于中国移动的") } else if (unicomSegments.contains(segment)) { println("这个号码是属于中国联通的") } else { println("暂不支持该号段识别") } } // 程序入口 def main(args: Array[String]): Unit = { identify("133") // 直接调用单例对象内的方法 } } ``` ## 六、总结 通过案例,我们掌握了Scala的数组、函数与单例对象语法: 1. **数组**Scala默认不可变,通过 `Array` 类创建,与C语言数组逻辑一致。 2. **函数**:强制声明返回类型,`Unit` 对应C语言的 `void`。 3. **单例对象**:封装全局逻辑,替代C语言的全局函数,提升代码组织性。 Scala语法虽与C语言有差异,但核心逻辑相通,结合C语言基础理解更轻松!帮我整理成博客的格式
03-08
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值