Scala基础练习

本文档提供了Scala编程的基础练习,涵盖了变量声明、字符串操作、控制语句、函数、模式匹配、面向对象编程、函数式编程、隐式转换等内容。通过实例展示了如何使用Scala进行数据处理,包括数组、Map、Set的操作,以及函数如map、filter、reduce的应用。此外,还介绍了Scala的REPL环境和官方文档链接,方便深入学习。

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

https://learnxinyminutes.com/docs/zh-cn/scala-cn/
/*
REPL(读取-求值-输出循环 Read-Eval-Print Loop)
*/
进一步学习,官方文档
https://docs.scala-lang.org/

1. 基础

// 单行注释开始于两个斜杠
/* 多行知识
*/

//通过var或者val来声明变量,val声明是不可变的,var声明是可修改的

1 + 7

/* 上行的结果是:

scala> 1 + 7
res29: Int = 8

这意味着计算 1 + 7 的结果是一个 Int 类型的对象,其值为 8

注意 “res29” 是一个连续生成的变量名,用以存储您输入的表达式结果,
您看到的输出可能不一样。
*/

// String 有常见的 Java 字符串方法
“hello world”.length
“hello world”.substring(2,6)
“hello world”.replace(“C”,“3”)

// 字符串改写:留意前缀"s"
var n = 45
s"We have $n apples" // => “We have 45 apples”
var a = Array(11, 9, 6)
s"My second daughter is ${a(0) - a(2)} years old." // My second daughter is 5 years old.

// f 为格式化字符串
f"Square root of 122: ${math.sqrt(122)}%1.4f"
res9: String = Square root of 122: 11.0454

// 未处理的字符串,忽略特殊字符
raw"New line feed: \n. Carriage return: \r."

// 三个双引号可以使字符串跨越多行,并包含引号

val html = """<form id="daform">
                <p>Press belo', Joe</p>
                <input type="submit">
              </form>"""

// 正则表达式
// val () =
val input = “Enjoying this apple 2.17 times today”
val pattern = “”".apple ([\d.]+) times .""".r
val pattern(amountText) = input
=> String = 2.17

2. 函数

// def functionName(args…): ReturnType = {…}

def sumOfSquares(x: Int, y: Int): Int = {
val x2 = x * x
val y2 = y * y
x2 + y2
}

// 单行可以省略括号
def sumOfSquaresShort(x : Int, y: Int): Int = xx + yy

sumOfSquaresShort(3, 4)

// 默认参数
def addWithDefault(x: Int, y: Int = 5) = x + y

addWithDefault(1,2)
addWithDefault(1)

// 匿名函数
(x: Int) => xx
val sq: Int => Int = x=> x
x

// 匿名函数的调用
sq(10)

val addOne: Int => Int = _ + 1
val weirdSum: (Int, Int) => Int = (_ * 2 + _ * 3)
// 这里的_与前面的参数相互对应; 如果存在不对应的情况则会出错

weirdSum(1,2)
weirdSum(2,1)

// 在Scala中没有return
def foo(x: Int): Int = {
val anonFunc : Int => Int = {
z =>
if (z > 5)
z
else z+1
}
anonFunc(x)
}

3. 控制语句

1 to 5
val r = 1 to 5
r.foreach(print)
r foreach println
// Scala对点和括号的要求相当宽松

// while循环
var i = 0
while (i < 10) { println(“i” + i); i += 1}
i

// do while循环
var j = 1
do {
println(“x is still less than 10”)
j += 1
} while (j < 10)

// Scala 中尾递归是一种符号语言习惯的递归方式
def showNumbersInRange(a: Int, b: Int):Unit = {
print(a)
if (a < b) showNumbersInRange(a + 1, b)
}
showNumbersInRange(1,10)

// 条件语句
if (x == 1) println(“yeah”)
println(if (x == 10) “yeah” else “nope”)

4. 数据结构

val array = Array(1, 3, 5, 8)
array(0)

// Map: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Map
// Map的方法 get,+,- iterator
// filter、flatMap、 withFilter
val m = Map(“fork” -> “tenedor”, “spoon”-> “cuche”)
m(“fork”)

m.+(“my”)
m.+(“he”->“fork”)
m.+((“sd”,“sd”), (“ds”,“ds”))
m.get(“my”)

val safeM = m.withDefaultValue(“no lo se”)
safeM(“bottle”)

val s = Set(1,1,2,4)

s(0)
s(1)

(1, 2)
(4, 3, 2)

val divideInts = (x:Int, y:Int) => (x / y, x % y)
divideInts(10, 3)

// 要读取元祖的元素,使用 _._n, n是从1开始的元素索引
val d = divideInts(10, 3)
d._1
d._2

5. 面向对象编程

// 主要有四类: objects, classes, case classes, traits

class Dog(br:String) {
// 构造器代码在此
var breed: String = br
def bark = “Woof, woof!”

// 值和方法作用域假定为public, protected 和 private 关键字也是可以用的
private def sleep (hours: Int) = println(s"I’m sleeping for $hours hours")

// 抽象方法是没有方法体的方法。
// abstract class Dog(…) {…}
// def chaseAfter(what: String): String
}

val mydog = new Dog(“greybound”)
println(mydog.breed)
println(mydog.bark)

// object 关键字创造一种类型和该类型的单例。
// Scala的class常常也含有一个“伴生对象”,class中包含每个实例的行为,所有实例
// 共同的行为则放入object中。两者的区别和其他语言中类方法和静态方法类似。
// 请注意object 和class 可以同名

object Dog {
def allKonwnBreeds = List(“pitbull”, “shepherb”, “retriever”)
def createDog(breed: String) = new Dog(breed)
}

// Case类是具有额外内建功能的类。关于何时使用类和何时使用case类界线比较模糊,但通常类倾向于封装、多态和行为。类中的值一般是private
// 只有方法是暴露的。 Case类通常是放置不可变数据

case class Person(name: String, phoneNumber: String)

// 创建新实例,注意case类不需要使用“new”关键字
val george = Person(“George”, “1234”)
val kate = Person(“Kate”, “4567”)

// 使用
george.phoneNumber
Person(“George”, “1234”) == Person(“Kate”, “1236”)
val otherGeorge = george.copy(phoneNumber = “9876”)

6. 模式匹配

def matchPerson(person: Person): String = person match {

case Person(“George”, number) => "We found George! His number is " + number
case Person(“Kate”, number) => "We found Kate! His number is " + number
number
}

// 定义正则表达式
val email = “(.)@(.)”.r

def matchEverything(obj: Any): String = obj match {
// 匹配值
case “Hello world” => “Got the string Hello world”;
// 匹配类型
case x: Double => “Got a Double” + x
// 匹配指定条件
case x: Int if x > 10000 => “Got a pretty big number”
// 像之前一样匹配case类
case Person(name, number) => s"Got contact info for $name"
// 匹配正则表达式, 注意这里已经自动分组了
case email(name, domain) => s"Got email address n a m e @ name@ name@domain"
// 匹配元祖
case (a: Int, b: Double, c:String) => s"Got a tuple:$a, $b. $c"
// 匹配数据结构
case List(1, b, c) => s"Got a list with three elements and starts with 1: 1, $b, $c"
// 模式可以嵌套
case List(List((1, 2, “YAY”))) => “Got a list of list of tuple”

}

// trait
// traits 封装了方法和变量,和Interface相比,它的方法可以有实现。
// 但和类继承不同的是,Scala中类继承为单一继承,也就是说子类只能有一个父类和多个Traits混合

trait Philosophical{
def philosophze() {
println(“I consume memeory, therefore I am!”)
}
}

class Frog extends Philosophical{
override def toString: String = “gree”
}

val frog = new Frog
frog.philosophze()

// 用法, class Frog extend Animail(基类) with … with …

7. 函数式编程(map, filter, reduce)

// Scala 允许方法和函数作为其他方法和函数的参数和返回值

var add10: Int => Int = _ + 10
List(1, 2, 3).map(add10)

List(1, 2, 3).map(_ + 10)

List(“Dom”, “Bob”, “Natalia”) foreach(println)

// 组合子
// 译注: val sq: Int => Int = x => x*x
s.map(sq) // 映射

val sSquared = s.map(sq)

sSquared.filter(_ < 10) // 条件筛选
sSquared.reduce(_ + _) // 累加

// filter 函数接受一个 predicate (函数根据条件A返回) 并选择所有满足predicate的元素

List(1, 2, 3).filter(_ > 2)

// case class Person(name:String, age:Int)
List (
Person(name = “Dom”, phoneNumber = “123”),
Person(name = “Bob”, phoneNumber = “456”)
).filter(_.phoneNumber > “343”)

// Scala的foreach方法定义在某些集合中,接受一个函数返回Unit
// http://www.scala-lang.org/api/current/index.html#scala.collection.IterableLike@foreach(f:A=>Unit):Unit

var aListofNumbers = List(1, 2, 3, 4, 10, 20, 100)
aListofNumbers.foreach(x => println(x))

// For 推导式

// For 语句
// for( a <- 1 to 10 by -1 if n < 10; s = n*n) {…}
for {n <- s } yield sq(n)

val nSquared2 = for {n <- s} yield sq(n)

for {n <- nSquared2 if n < 10} yield sq(n)

for {n <- s; nSquared2 = n*n if nSquared2 < 10} yield sq(n)

/*
注意, 这些不是for循环,主要体现的是两个数据集合之间的关系
*/

8. 隐式转换

// 这部分用于理解,不用细看
// 可以通过“implicit"声明任何值(val, 函数, 对象等) 为隐式值

implicit val myImaplicitInt = 100
myImaplicitInt + 2

9. 杂项

// 导入类
import java.io.PrintWriter

import scala.collection.immutable.List

// 导入所有子包
import scala.collection.immutable._

// 一条语句导入多个类
import scala.collection.immutable.{List, Map}

// 使用 ”=>“ 对导入进行重命名
import scala.collection.immutable.{ List => ImmutableList }

// 导入所有类,排除其中一些。下面的语句排除了Map和Set
import scala.collection.immutable.{Map => _, Set => _, _}

// 在Scala文件用object 和单一的main方法定义程序入口

object Application {
def main(args: Array[String])={
// stuff goes here
}
}

// 文件可以包含多个class 和 object, 用scalac编译源文件

// 输入和输出

// 按行读文件
import scala.io.Source
for(line <- Source.fromFile("./myfile.txt").getLines())
println(line)

// 用Java的PrintWriter写文件,注意目录是基于工程的路径
val writer = new PrintWriter("./myfile.txt")
writer.write(“Writing line for line” + util.Properties.lineSeparator)
writer.write("Another line here " + util.Properties.lineSeparator)
writer.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值