我眼中的Scala
作者:互联网
The Scala Programming Language
Scala combines object-oriented and functional programming in one concise,high-level language.
Scala’s static types help avoid bugs in complex applications, and its JVM and JavaScript runtimes let you build high-performance systems with easy access to huge ecosystems of libraries.
Scala in a Nutshell
- Seamless java interop
Scala runs on the JVMS, so Java and Scala stacks can be freely mixed for totally seamless integration。 - Type Inference
So the type system doesn’t feel so static. Don’t work for the type system. Let the type system work for you! - concurrency & distribution
Use data-parallel operations on collections, use actors for concurrency and distribution, or futhres for asynchronous programming。 - traits
Combine the flexibility of Java-style interfaces with the power of classes. Think principled multiple-inheritance。
-Pattern Matching
Think “switch” on steroids. Match against class hierarchies, sequences, and more. - Higher-Order functions
Functions are first-class objects. Cmpose them with guaranteed type safety. Use them anywhere, pass them to anything。
数据类型 - Byte 8bit的有符号数字
- Short 16bit有符号数字
- Int 32bit有符号数字
- Long 64bit有符号数字
- Float 32bit有符号数字
- Double 64bit双精度浮点数
- Char 16bit Unicode字符
- String 字符串
- Boolean 布尔类型
- Unit 表示无值,和其他语言中的void等同
- Null 空值或者空引用
- Nothing 所有其他类型的子类型,表示没有值
- Any 所有类型的超类,任何实例都属于Any类型
- AnyRef 所有引用类型的超类
- AnyVal 所有值类型的超类
类和对象
/**
* 1,Scala object 相当于java中的单例,object中定义的全是静态的。Object不可以传参
* 2,Scala 定义变量使用var, 定义常量使用val;且不需要指定类型,Scala有类型推断机制
* 3,Scala类中可以传参,传参一定要指定类型;有了参数,就默认有了构造函数。
* 4,类中重写构造时,构造第一行必须先调用默认的构造,def this(...){....}
* 5,Scala中new Class时,除了构造方法之外的所有方法都不执行,其他都执行
* 6,Object和Class类名称一样时,互为伴生类和伴生对象。伴生类和伴生对象可以互相访问私有变量
* 7,Object中有参数,必然实现了apply方法
*/
class ScalaOne(xname:String, xage:Int) {
private val name = xname
val age = xage
var gender = "M"
def show()={
println("name is "+ name + "age is " + age + "sex is " + ScalaOne.sex)
}
def this(yname:String, yage:Int, ygender:String){
this(yname, yage)
this.gender = ygender
}
}
object ScalaOne {
val sex = "男"
def apply(i:Int)= {
println("score is " + i)
}
def apply(i:Int, s:String) = {
println(s+ "score is " + i)
}
def main(args: Array[String]): Unit = {
val i = 100
val p = new ScalaOne("小明", 20)
val q = new ScalaOne("小强", 12, "V")
println(p.name+"的年纪"+p.age)
p.show()
ScalaOne(10)
}
}
方法和函数
import java.util.Date
/**
* 1,方法的定义
* 1)方法体中最后返回值可以使用return,如果使用了return,那么方法体的返回值类型一定要指定
* 2)方法体中没有return,默认方法体最后一行作为返回值,返回值类型自动推断
* 3)定义方法参数,要指明类型
* 4)注意添加方法和方法体之间的等号,类型推断除返回值
*/
object ScalaTwo {
def main(args: Array[String]): Unit = {
def max(a: Int, b: Int) = {
if (a > b)
a
else
b
}
val result = max(1, 2)
println(result)
/**
* 递归方法,需要显示的指明递归返回类型
*/
def fun(num: Int): Int = {
if (num == 1) {
1
} else {
num * fun(num - 1)
}
}
println(fun(5))
/**
* 参数有默认值的方法
*/
def fua(a: Int = 10, b: Int = 20) = {
a + b
}
println(fua())
println(fua(b = 21))
println(fua(100, 200))
/**
* 可变长参数的方法,在参数后面添加一个*
*/
def fub(s: String*) = {
/*
for(elem<-s)
{
println(elem)
}
*/
s.foreach(elem => {
println(elem)
}) //匿名函数
s.foreach(println(_)) //elem在方法体中,只用到了一次,可以用_替代
s.foreach(println) //方法只需要一个参数时,参数可以省略
}
fub("hello", "a", "b", "c")
/**
* 匿名函数 ()=> {}
* => 就是 匿名函数,多用于方法的参数是函数时,常用匿名函数
**/
def fuc = (a: Int, b: Int) => {
a + b
}
/**
* 嵌套方法
*/
def fud(num: Int) = {
def fu1(a: Int): Int = {
if (a == 1) {
1
} else {
a * fu1(a - 1)
}
}
fu1(num)
}
println(fud(6))
/**
* 偏应用函数,函数只有一个参数变,其他不变,可以调用偏应用函数
*/
def showLog(date: Date, log: String) = {
println(s"date is $date , log is $log")
}
val date = new Date()
showLog(date, "a")
showLog(date, "b")
showLog(date, "c")
def fue = showLog(date, _: String)
fue("a")
fue("b")
fue("c")
/**
* 高阶函数
* 1)方法的参数是函数
* 2)方法的返回是函数
* 3)方法的参数和返回都是函数
*/
//方法的参数是函数
def f1(f: (Int, Int) => Int, b: String) = {
val i: Int = f(100, 200)
println(b + "是" + i)
}
val res = f1((a: Int, b: Int) => {
a * b
}, "scala")
println(res)
//方法的返回是函数
def f3(s: String) = {
def fc(s1: String, s2: String): String = {
s1 + "'" + s2 + "&"
}
fc _
}
println(f3("aaa")("bbb", "cccc"))
/**
* 柯里化函数
*/
def fn(a:Int, b:Int)(c:Int, d:Int)={
a+b+c+d
}
println(fn(1, 2)(2, 3))
}
}
数组和List集合
import scala.collection.mutable.ListBuffer
object ScalaThree {
def main(args: Array[String]): Unit = {
val s = "bjsxt"
val s1= "BJSXT"
println(s.indexOf('b')) //返回字符串下标
println(s.equals(s1))
println(s.equalsIgnoreCase(s1))
val arr = Array[String]("a", "b", "c", "d") //括号内是初始值
arr.foreach(println)
val arr1 = new Array[Int](3) //括号内部是元素个数,默认值是0
arr1(0) = 100
arr1(1) = 200
arr1(2) = 300
arr1.foreach(println)
val a1 = Array("a", "b", "c")
val a2 = Array("d", "e", "f")
val arrays: Array[String] = Array.concat(a1, a2)
arrays.foreach(println)
//可变数组
import scala.collection.mutable.ArrayBuffer
val muarr = ArrayBuffer[Int](1, 2, 3, 4, 5, 6, 7)
muarr.append(123)
val list = List[Int](1, 2, 3) //创建集合时,要指定泛型
list.foreach(println)
val list1 = List[String]("hello scala", "hello java", "hello spark")
val sses: List[Array[String]] = list1.map(s => {
s.split(" ")
})
sses.foreach(arr=>{arr.foreach(println)})
val sses1: List[String] = list1.flatMap(s=>{s.split(" ")})
sses1.foreach(println)
list1.filter(s=>s.contains("hello")).foreach(println)
val i: Int = list1.count(s=>s.length>4)
println(i)
//可变的list
val mulist = ListBuffer[Int](1, 2, 3)
mulist.append(4, 5, 6)
}
}
Set和Map
import scala.collection.immutable
import scala.collection.mutable
object ScalaFour {
def main(args: Array[String]): Unit = {
val set = Set[Int](1, 2, 3, 3, 2, 1) //指定泛型
set.foreach(println) //无序去重
val set1 = Set[Int](3, 4, 5, 6)
val ints: Set[Int] = set.intersect(set1) //类似 set & set1
val res: Set[Int] = set.diff(set1) //类似set &` set1
val ints1: Set[Int] = set.filter(elem=>elem>=2)
//可变长的set
val muset = mutable.Set[Int](0, 1, 2, 3)
muset.foreach(println)
val map = Map[String, Int]("a"->100, ("c", 400))
println(map)
map.foreach(println)
val rr: Int = map.get("a").getOrElse(100) //map.get(key),返回Option类型(some和None)
val keys: Iterable[String] = map.keys
keys.foreach(key=>{
println(s"key is $key"+map.get(key))
})
val values: Iterable[Int] = map.values
}
}
元组
元组可以包含不同类型的元素,元组的值是通过将单个的值包含在圆括号里面的。
object ScalaFour {
def main(args: Array[String]): Unit = {
val tuple = new Tuple1(1)
val value: Int = tuple._1
println(value)
val tuples = Tuple3(1, "2", 'c')
println(tuples._3) //元组最多支持22个元素
}
}
trait
trait Read{
def read(name:String)={
println("$name is reading...")
}
}
trait Listen{
def listen(name:String)={
println("$name is listening...")
}
}
class Person() extends Read with Listen{ //一个类多个trait,第一个关键字使用extends,之后使用with
}
trait IsEqual{
def isEqu(o:Any):Boolean //trait中可以有方法体的实现,也可以有方法的不实现。类继承实现未实现方法
def isNotEqu(o:Any):Boolean={
!isEqu(o)
}
}
class Point(xx:Int, xy:Int) extends IsEqual {
val x = xx
val y = xy
override def isEqu(o: Any) = {
o.isInstanceOf[Point]&&o.asInstanceOf[Point].x == this.x //判断是否是一个实例,判断是否相同
}
}
object ScalaFour {
def main(args: Array[String]): Unit = {
val p = new Person()
p.read("zhangsan")
p.listen("lisi")
}
}
模式匹配
/**
* Match 模式匹配
* 1,case _ 放在最后,意外情况
* 2,模式匹配可以匹配值,还可以匹配类型
* 3,匹配过程中会有数值的转换,1.0变成1整型
* 4,从上往下匹配,匹配上会终止
*/
object ScalaFour {
def main(args: Array[String]): Unit = {
val tp = (1, 1.2, "abc", 'c', true)
val iterator: Iterator[Any] = tp.productIterator
iterator.foreach(MatTest)
}
def MatTest(o:Any)={
o match {
case 1 => println("value is 1")
case i:Int => println(s"type is Int, value is $i")
case e:Double => println("type is Double, value is $e")
case s:String => println("type is String, value is $s")
case _ => println("no match ....")
}
}
}
样例类
/**
* 样例类
* 样例类实现了类构造参数的getter方法(构造参数默认声明为val),当构造参数声明为var类型,也可以默认实现setter方法
* 默认实现了toString, equals, copy 和 hashCode方法
* 样例类可以new,也可以不用new
*/
case class P(var name:String, age:Int)
object ScalaFour {
def main(args: Array[String]): Unit = {
val p1 = P("sss", 1)
val p2 = P("sss", 1)
println(p1.equals(p2))
println(p1)
}
}
隐式转换
隐式转换在Scala编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。
- 隐式值和隐式参数
隐式值是在定义参数前面加上implict,隐式参数是指定义方法时,方法中的部分参数是由implict修饰【必须使用柯里化的方式,将隐式参数写在后面的括号中】。隐式参数的作用:当调用方法时,不必传入参数,Scala会自动在作用域范围内寻找隐式值自动传入。
object ScalaFour {
def sayName(implicit name:String): Unit ={ //隐式参数
println(s"$name is saying")
}
def main(args: Array[String]): Unit = {
implicit val name = "abcdef" //隐式值
sayName
}
}
- 隐式转换函数
隐式转换函数使用关键字implict修饰的方法。当Scala运行时,假设如果A类型变量调用了method()方法,发现A类型的变量没有method方法,而B类型的变量有method()方法,会在作用域内寻找有没有隐式转换函数将A类型换成B类型,如果有隐士转换函数,那么A类型就可以调用method方法。
Actor通信
spark1.6 使用Actor
spark2.9 使用NIO
标签:String,val,Scala,Int,foreach,println,眼中,def 来源: https://blog.csdn.net/qq_43057549/article/details/112263373