有道云链接
在有道云写的 到这里全乱了
https://note.youdao.com/ynoteshare1/index.html?id=acf94e8ed202685f06a31f721029d05a&type=note
3 子类可以通过 extends 继承 trait并且 可以在方法上添加override关键字
9 函数柯丽化 Multiple Parameter Lists
1 _使用
2 官网
1 在线练习
3 基础
1 表达式
1 + 1
2 不可变变量 val
val x = 1 + 1
不能重新赋值
3 可变变量 var
var x = 1 + 1 x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9
4 代码块 Blocks
println({
val x = 1 + 1
x + 1
}) // 3
代码块最后一行代码代表代码块的返回值
5 函数 Functions
Functions are expressions that have parameters, and take arguments.
1 参数 2
函数的=>左边是参数列表
右边是 包含参数 的表达式
- 可以是匿名函数
如(x: Int) => x + 1
- 可以是有名字的函数
val addOne = (x: Int) => x + 1
println(addOne(1)) // 2
- 可以是无参的函数
val getTheAnswer = () => 42
println(getTheAnswer()) // 42
6 方法 Methods
Methods are defined with the def keyword. def is followed by a name, parameter list(s), a return type, and a body:
1 方法名 2 参数列表 3 返回值类型 4 方法体
def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3
多参数
def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9
无参数
def name: String = System.getProperty("user.name") println("Hello, " + name + "!")
多行表达式的 最后一行是返回值
def getSquareString(input: Double): String = { val square = input * input square.toString } println(getSquareString(2.5)) // 6.25
7 类 Classes
You can define classes with the class keyword, followed by its name and constructor parameters
class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) }
返回值是Unit 代表没有返回值 类似java的void 但是scala所有表达式都必须有一个值,所以有一个单例Unit对象代表为空{}
8 Case 类 Case Classes
通过 case class关键字创建 创建case class类无需通过new 关键字
通常情况下 case classes 是不可变的,他们通过value进行比较,和class不同(class是通过比较引用是否相等)
在模式匹配 pattern matching的时候特别有用
9 Objects
是 class类的单例对象
Objects are single instances of their own definitions. You can think of them as singletons of their own classes.
You can define objects with the object keyword:
10 Traits
类似于java接口吧
这个可以实现多继承 但是 class只能单继承
Traits are abstract data types containing certain fields and methods. In Scala inheritance, a class can only extend one other class, but it can extend multiple traits.
1通过 trait关键字创建
2可以有默认方法的实现
3 子类可以通过 extends 继承 trait并且 可以在方法上添加override关键字
11 主方法 Main Method
像 java类一样通过main方法执行
Using an object, you can define the main method as follows:
object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") }
4 统一类型
scala中所有值都有类型,包括数值和函数
1 Any
所有类型的父类 定义了一些通用方法 如equals hashcode toString
Any有两个直接子类 AnyVal 和 AnyRef
2 AnyVal
代表值类型 有九种
- Unit
- Byte
- Char
- Short
- Int
- Float
- Double
- Long
- Boolean
3 AnyRef
代表引用类型
类型转换
5 默认参数值
注意 如果是从java调用scala 代码
那么参数不可省略
6 Tuples
不可变
In Scala, a tuple is a value that contains a fixed number of elements, each with its own type. Tuples are immutable.
val ingredient = ("Sugar" , 25)
像上述创建了一个String 和Int
类型推断出事(String,Int) 是Tuple2[String,Int]的缩写
tuples有很多种如tuple2 ,tuple3 ... 最大是tuple22
获取元素
其中一种方式是通过position 通过_1 _2
println(ingredient._1) // Sugar println(ingredient._2) // 25
Tuples和case classes 的区别
case classes 有指定名字的元素
7 高阶函数
Higher order functions take other functions as parameters or return a function as a result. This is possible because functions are first-class values in Scala. The terminology can get a bit confusing at this point, and we use the phrase “higher order function” for both methods and functions that take functions as parameters or that return a function.
1 使用Function作为参数
高阶函数就是可以把其他functions 作为参数或者返回一个function作为返回值
1 初次版本
比如对于map函数应用 变化
val salaries = Seq(20000, 70000, 40000) val doubleSalary = (x: Int) => x * 2 val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000)
2 匿名内部类
为了减少代码 可以通过匿名函数
val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000)
3使用_作为参数占位符
因为编译器可以进行类型推断 所以可以直接使用_
val salaries = Seq(20000, 70000, 40000) val newSalaries = salaries.map(_ * 2)
2 使用 Method 强制转化为Function
可以把method参数转为 function
示例
case class WeeklyWeatherForecast(temperatures: Seq[Double]) { private def convertCtoF(temp: Double) = temp * 1.8 + 32 def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF) // }
This is possible because the compiler coerces convertCtoF to the function x => convertCtoF(x) (note: x will be a generated name which is guaranteed to be unique within its scope).
3 Functions 接收 Functions
使用高阶函数减少重复代码
4 Functions 返回 functions
注意 def
1方法名 urlBuilder
2参数列表 (ssl:Boolean ,domain:String)
3:后面是返回值类型是一个匿名函数 (String,String)=>String
4 =右边是方便体
8 循环方法 Nested Methods
9 函数柯丽化 Multiple Parameter Lists
trait Iterable[A] { ... def foldLeft[B](z: B)(op: (B, A) => B): B ... }
foldLeft 从左到右调用一个二元运算 作用于初始值 z 和迭代器中的每一个元素上
val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val res = numbers.foldLeft(0)((m, n) => m + n) println(res) // 55
用例
1 单一类型推断
方法定义
def foldLeft1[A, B](as: List[A], b0: B, op: (B, A) => B) = ???
原始调用方式
def firstWay = foldLeft1[Int, Int](numbers, 0, _ + _) def secondWay = foldLeft1(numbers, 0, (a: Int, b: Int) => a + b)
改进调用方式
2 隐式 参数
指定特定参数列表为隐式列表
def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ???
10 Case Classes
三要素
最简单的case class定义 需要
- case class关键字
- 类名
- 参数列表 (可以为空)
创建
不使用new 因为case classes 有一个apply方法完成object的构建
当case classes 有类变量时 都是不可变的val
case class Message(sender: String, recipient: String, body: String) val message1 = Message("guillaume@quebec.ca", "jorge@catalonia.es", "Ça va ?") println(message1.sender) // prints guillaume@quebec.ca message1.sender = "travis@washington.us" // this line does not compile
可以使用 var变量 但是不建议
比较
case classes 之间的比较 是按值比较 而不是引用
拷贝
使用copy 方法