日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Scala简明教程

發布時間:2025/3/21 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Scala简明教程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Scala簡明教程

目錄
? ?? ?變量聲明
? ?? ?函數
? ?? ?包package
? ?? ?數據結構
? ?? ?字符串
? ?? ?控制流程
? ?? ?模式匹配
? ?? ?面向對象
? ?? ?泛型
? ?? ?注解
? ?? ?Implicit
? ?? ?空對象Nil,Null,null,Unit,Nothing,None


? ?? ?Scala是一門多范式(multi-paradigm)的編程語言。
? ?? ?Scala源代碼被編譯成Java字節碼,所以它可以運行于JVM之上,并可以調用現有的Java類庫。
洛桑聯邦理工學院的Martin Odersky于2001年基于Funnel的工作開始設計Scala。Funnel是把函數式編程思想和佩特里網相結合的一種編程語言。Odersky先前的工作是Generic Java和javac。Java平臺的Scala于2003年底/2004年初發布。該語言第二個版本,v2.0,發布于2006年3月。


Scala是面向對象的,比Java更徹底

一切皆為對象, 數值,函數都是對象
全部支持函數式編程
包括函數即是對象,lambda,currying, type inference, immutability, lazy evaluation, and pattern matching
強大的靜態類型系統
algebraic data types, covariance and contravariance, higher-order types, anonymous types, generic classes, upper and lower type bounds, inner classes and abstract types as object members, compound types, explicitly typed self references , views and polymorphic methods
其它Java不支持的功能:

operator overloading, optional parameters, named parameters, raw strings, and no checked exceptions
2009年4月,Twitter宣布他們已經把大部分后端程序從Ruby遷移到Scala,其余部分也打算要遷移。這里有一篇文章解釋Twitter為什么使用Scala編程語言。
Engineer-to-Engineer Series Programming Languages Programming Languages Scala Talks
Coursera把Scala作為服務器語言使用。Why we love Scala at Coursera
一些Scala學習資料:

Scala documentation
Learning Scala
Effective Scala
Scala School
Scala cheatsheets


大數據生態圈中的Kafka和Spark都是由Scala開發的,這也是我為什么學習Scala的原因之一。
作為一個十多年Java程序員,同時在學習Scala和go這兩種語言。 學習的過程中感覺go語言太好學了, 入手很快, 而Scala的語法和類C語言如Java,C#等很不一樣, 很多語法的技巧在里面。 基于此,我特地整理了這篇文章。 簡單扼要的介紹Scala語言的知識點,尤其是和Java不太一樣的地方。

$變量聲明
  • var x = 5
  • var x:Double = 5
  • val y = 7
  • 復制代碼
    var聲明變量, val聲明常量, 類型可省略, Scala可以推斷出數據類型
    函數

  • def f(x: Int) = { x*x }
  • def f(x: Any): Unit = println(x)
  • 復制代碼

    定義函數, 返回值類型可省略, =等號后面可以是塊定義或者表達式。

  • reply()
  • reply
  • 復制代碼
    無參數的函數調用時可以省略括號。

  • names foreach (n => println(n))
  • names mkString ","
  • optStr getOrElse "<empty>"

  • 復制代碼
    一個參數時可以使用infix寫法
    infix操作符可以定義如下:

  • ? ?class MyBool(x: Boolean) {
  • def and(that: MyBool): MyBool = if (x) that else this
  • def or(that: MyBool): MyBool = if (x) this else that
  • def negate: MyBool = new MyBool(!x)

  • def not(x: MyBool) = x negate; // semicolon required here
  • def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y)
  • }

  • //更多例子
  • 5.+(3); 5 + 3
  • (1 to 5) map (_*2)
  • def f(x: R)
  • def f(x: => R)

  • 復制代碼
    第一個call-by-value ,第二個call-by-name(lazy parameters)

  • (x:R) => x*x
  • 復制代碼

    匿名函數(lambda表達式)
    =>可以由 ? 字符替代(\u21D2),同樣 <-和 ->也可以由單個的字符取代: ← 和 →

  • (1 to 5).map(_*2)
  • (1 to 5).reduceLeft( _+_ )
  • 復制代碼

    下劃線代表替代, 更多的下劃線功能參看 討論

  • (1 to 5).map(2*)
  • 等價
  • (1 to 5).map(2* _)
  • (1 to 5).map { val x=_*2; println(x); x }
  • (1 to 5) filter {_%2 == 0} map {_*2}
  • 復制代碼

    匿名函數的塊風格實現,最后一個語句作為返回值

  • def compose(g:R=>R, h:R=>R) = (x:R) => g(h(x))
  • val f = compose({_*2}, {_-1})
  • 復制代碼

    多個塊作為參數

  • val zscore = (mean:R, sd:R) => (x:R) => (x-mean)/sd??//currying, obvious syntax.
  • def zscore(mean:R, sd:R) = (x:R) => (x-mean)/sd??//currying, obvious syntax
  • def zscore(mean:R, sd:R)(x:R) = (x-mean)/sd? ?? ? //currying, 語法糖,也叫參數分組. 但是必須按照下面的語法調用:
  • val normer = zscore(7, 0.4)_? ?? ?? ?//需要尾部的下劃線,僅限于上面一行的語法糖
  • def sum(args: Int*) = args.reduceLeft(_+_)
  • 復制代碼

    可變參數
    $ 包package


  • import scala.collection._??//通配符導入,類似java中的.*
  • import scala.collection.Vector
  • import scala.collection.{Vector, Sequence}??//導入多個
  • import scala.collection.{Vector => Vec28}??//別名.
  • import java.util.{Date => _, _}??//除了Date,其它都導入
  • package pkg at start of file
  • package pkg { ... }
  • 復制代碼

    一般語句后面可以省略 ;
    & 數據結構


  • (1,2,3)
  • var (x,y,z) = (1,2,3)
  • 復制代碼

    tuple類型

  • var xs = List(1,2,3)
  • xs(2)
  • 復制代碼

    List類型

  • 1 :: List(2,3)
  • List(1, 2) ::: List(2, 3)
  • List(1, 2) ++ Set(3, 4, 3)
  • 復制代碼

    一些特殊的操作符


  • 1 to 5 same as 1 until 6
  • 1 to 10 by 2
  • 復制代碼

    range

    $ 字符串



  • val name = "James"
  • println(s"Hello, $name") // Hello, James
  • println(s"1 + 1 = ${1 + 1}")
  • 復制代碼
    s前綴, 替換字符串中的變量或表達式

  • val height = 1.9d
  • val name = "James"
  • println(f"$name%s is $height%2.2f meters tall") // James is 1.90 meters tall
  • 復制代碼

    f前綴, printf風格的格式化


  • scala> raw"a\nb"
  • res1: String = a\nb
  • 復制代碼

    raw前綴, 原始字符,不轉義


  • scala> "a".r
  • res1: scala.util.matching.Regex = a
  • 復制代碼

    r后綴, 正則表達式
  • implicit class JsonHelper(private val sc: StringContext) extends AnyVal {
  • ??def json(args: Any*): JSONObject = ...
  • }
  • val x: JSONObject = json"{ a: $a }"
  • 復制代碼

    自定義的字符串攔截器
    $ 控制流程

  • if (check) happy else sad
  • if (check) happy? ?//下面一樣
  • if (check) happy else ()
  • 復制代碼

    >> if語句
  • while (x < 5) { println(x); x += 1}
  • do { println(x); x += 1} while (x < 5)
  • 復制代碼

    while語句
  • import scala.util.control.Breaks._
  • breakable {
  • ??for (x <- xs) {
  • ? ? if (Math.random < 0.1) break
  • ??}
  • }
  • for (x <- xs if x%2 == 0) yield x*10 //與下面的等價
  • xs.filter(_%2 == 0).map(_*10)
  • for ((x,y) <- xs zip ys) yield x*y //與下面的等價
  • (xs zip ys) map { case (x,y) => x*y }
  • for (x <- xs; y <- ys) yield x*y??//與下面的等價
  • xs flatMap {x => ys map {y => x*y}}
  • for (x <- xs; y <- ys) { //雙層嵌套,類似for {for {}}
  • println("%d/%d = %.1f".format(x,y, x*y))
  • }
  • for (i <- 1 to 5) {
  • println(i)
  • }
  • for (i <- 1 until 5) {
  • println(i)
  • }
  • 復制代碼

    $ 模式匹配

  • (xs zip ys) map { case (x,y) => x*y }
  • val v42 = 42
  • Some(3) match {
  • case Some(`v42`) => println("42")
  • case _ => println("Not 42")
  • }
  • val UppercaseVal = 42
  • Some(3) match {
  • case Some(UppercaseVal) => println("42")
  • case _ => println("Not 42")
  • }
  • 復制代碼

    case class自動生成equals和toString,參數相同則==返回true
    $ 面向對象
    ? ? 沒有訪問修飾符的class或者類成員默認都是public類型的。

  • class C(x: R) //等價于
  • class C(private val x: R)
  • var c = new C(4)
  • 復制代碼
    >> 參數是private類型

  • class C(val x: R)
  • var c = new C(4)
  • c.x
  • 復制代碼

    >> 參數是public類型

  • class C(var x: R) {
  • assert(x > 0, "positive please") //constructor is class body,所以你可以在這里寫一些語句
  • var y = x??//public成員
  • val readonly = 5 //只能讀取,無法set
  • private var secret = 1 //private成員
  • def this = this(42) //其它構造函數
  • }
  • new{ ... }
  • abstract class D { ... }
  • class C extends D { ... }??//繼承
  • class D(var x: R)
  • class C(x: R) extends D(x)??//繼承和構造函數參數. (wishlist: automatically pass-up params by default)
  • object O extends D { ... }??//object定義單例
  • trait T { ... } //traits.
  • class C extends T { ... } //實現接口. no constructor params. mixin-able.
  • class C extends D with T { ... }
  • trait T1; trait T2 //多個traits
  • class C extends T1 with T2
  • class C extends D with T1 with T2
  • class C extends D { override def f = ...} //必須聲明override
  • new java.io.File("f")??//產生類對象
  • List(1,2,3)??
  • classOf[String] //類字面值
  • x.isInstanceOf[String] //運行時檢查
  • x.asInstanceOf[String] //運行時cast
  • x: String //編譯時指明
  • final class A{
  • ??final val x = 1
  • ??var y = 2
  • }
  • sealed class B
  • 復制代碼

    final和sealed
    ? ?? ?對于內部類, inst1.InnerClass1 和inst2.InnerClass1是不同的類型,這和Java不一樣。 如果想使用相同的類型,使用Class#InnerClass1
    $ 泛型


  • def mapmake[T](g:T=>T)(seq: List[T]) = seq.map(g)
  • 復制代碼

    >> 方法帶類型參數

  • class Stack[T] {
  • var elems: List[T] = Nil
  • def push(x: T) { elems = x :: elems }
  • def top: T = elems.head
  • def pop() { elems = elems.tail }
  • }
  • 復制代碼

    >> 類帶類型參數

  • <p>class A
  • class B extends A
  • def test[T <: A](t: T) = {}
  • test(new A)
  • test(new B) //error
  • Upper Type Bounds
  • class A
  • class B extends A
  • class C extends B
  • def test[T <: A](t: T) = {}
  • test[A](new A)
  • test[C](new C) //error</p>
  • 復制代碼 >>Lower Type Bounds
  • class Test[+T](x: T)
  • 復制代碼 >> covariant 針對類
  • class A
  • class B extends A
  • class C extends B
  • class Test[T](x: T)
  • val c = new Test(new C)
  • val t:Test[B] = c //Note: C <: B, but class Test is invariant in type T. You may wish to define T as +T instead. (SLS 4.5)
  • val a = new Test(new A)
  • val t:Test[B] = a //Note: A >: B, but class Test is invariant in type. You may wish to define T as -T instead. (SLS 4.5)
  • 復制代碼
    >>invariant

  • class Test[-T](x: T)
  • 復制代碼

    >>contravariant 針對類
    總結:
    1) 協變
    [+T], covariant (or “flexible”) in its type parameter T,類似Java中的(? extends T), 即可以用T和T的子類來替換T,里氏替換原則。
    2) 不變
    不支持T的子類或者父類,只知支持T本身。
    3) 逆變
    [-T], contravariant, 類似(? supers T) 只能用T的父類來替換T。是逆里氏替換原則。
    4) 上界
    只允許T的超類U來替換T。 [U >: T]
    5) 下界
    只允許T的子類U來替代T。 [U <: T]
    注解


  • @interface SourceURL {
  • public String value();
  • public String mail() default "";
  • }
  • 復制代碼

    使用

  • @interface Source {
  • public String URL();
  • public String mail();
  • }

  • @Source(URL = "http://coders.com/",
  • mail = "support@coders.com")
  • class MyScalaClass ...
  • 復制代碼

    簡寫(對于屬性名為value的特殊屬性)


  • @interface SourceURL {
  • ? ?public String value();
  • ? ?public String mail() default "";
  • ? ?}
  • ? ?@SourceURL("http://coders.com/")
  • class MyScalaClass ..
  • @SourceURL("http://coders.com/",
  • mail = "support@coders.com")
  • class MyScalaClass .
  • 復制代碼

    Implicit
    implicit parameters 隱式參數
    如果參數定義為implicit,那么在調用的如果沒設置, 那么參數會自動提供。
    隱式參數與缺省參數是完全不一樣的。缺省參數是函數定義方設定了一個缺省值,在調用者沒有指明時將使用該缺省值。 隱式參數則不同,最終是會由調用方指定參數值,只是不一定在調用的語句里指定而已。編譯器在發現缺少隱式參數時,會在程序范圍內尋找符合類型的隱式值,如果找不到則編譯會失敗。

  • abstract class Logger {def log(s: String)}
  • class FileLogger extends Logger {
  • ??def log(s: String) {println("Log in file: " + s)}
  • }
  • class StdoutLogger extends Logger {
  • ??def log(s: String) {println("Stdout: " + s)}
  • }
  • def Add(a: Int, b: Int)(implicit logger: Logger) {
  • ??val sum = a + b
  • ??logger.log("%d + %d = %d".format(a, b, sum ))
  • }
  • implicit val log = new FileLogger
  • Add(1,2)
  • Add(2,3)(new StdoutLogger) //you may do it explicitly
  • 復制代碼

    如果上述代碼沒有implicit val log = new FileLogger這一句,在代碼范圍內也沒有其他的Logger類型的implicit值,編譯器會報錯.
    反之,如果能找到Logger類型的隱式值,編譯器會將該隱式值作為參數傳遞過去。
    implicit class 隱式類
    A new language construct is proposed to simplify the creation of classes which provide extension methods to another type.
  • implicit class RichInt(n: Int) extends Ordered[Int] {
  • def min(m: Int): Int = if (n <= m) n else m
  • ...
  • }
  • 復制代碼

    被轉換為
  • class RichInt(n: Int) extends Ordered[Int] {
  • def min(m: Int): Int = if (n <= m) n else m
  • ...
  • }
  • implicit final def RichInt(n: Int): RichInt = new RichInt(n)

  • 復制代碼

    >> implicit method 隱式轉換
    有時候,你并不需要指定一個類型是等/子/超于另一個類,你可以通過轉換這個類來偽裝這種關聯關系。一個視界指定一個類型可以被“看作是”另一個類型。這對對象的只讀操作是很有用的。
    隱函數允許類型自動轉換。更確切地說,在隱式函數可以幫助滿足類型推斷時,它們允許按需的函數應用。例如:

  • implicit def strToInt(x: String) = x.toInt
  • val y: Int = "123"
  • 復制代碼

    >> view
    view
    ,就像類型邊界,要求對給定的類型存在這樣一個函數。您可以使用<%指定類型限制,例如:

  • class Container[A <% Int] { def addIt(x: A) = 123 + x }
  • 復制代碼

    這是說 A 必須“可被視”為 Int 。
    方法可以通過隱含參數執行更復雜的類型限制。例如,List支持對數字內容執行sum,但對其他內容卻不行。可是Scala的數字類型并不都共享一個超類,所以我們不能使用T <: Number。相反,要使之能工作,Scala的math庫對適當的類型T 定義了一個隱含的Numeric[T]。 然后在List定義中使用它:


  • sum[B >: A](implicit num: Numeric[B]): B
  • 復制代碼

    如果你調用List(1,2).sum(),你并不需要傳入一個 num 參數;它是隱式設置的。但如果你調用List("whoop").sum(),它會抱怨無法設置num。
    在沒有設定陌生的對象為Numeric的時候,方法可能會要求某種特定類型的“證據”。這時可以使用以下類型-關系運算符:
    | | |
    |---|---|
    |A =:= B | A 必須和 B相等|
    |A <:< B | A 必須是 B的子類|
    |A <%< B | A 必須可以被看做是 B|


  • class Container[A](value: A) { def addIt(implicit evidence: A =:= Int) = 123 + value }
  • 復制代碼

    $ 空對象Nil,Null,null,Unit,Nothing,None

    1) Nothing 是trait,定義為:final trait Nothing extends Any。Nothing處于Scala類型體系的最底層,是所有類型的子類型,Nothing沒有實例。
    2) Null 是trait,定義為:final trait Null extends AnyRef 。Null是所有引用類型的子類型,唯一的一個實例是null。
    3) null是Null的實例,類似Java中的null
    4) Nil 是case object,定義為case object Nil extends List[Nothing], 代表一個空list,長度為0。由于Scala中的List是協變的,因此無論T是何種類型,Nil都是List[T]的實例。
    5) None 是case object,定義為:case object None extends Option[Nothing],代表不存在的值。Option有兩個實例。None和Some

    6) Unit 是class,定義為:abstract final class Unit extends AnyVal。Unit跟Java中的void相當,當一個方法不返回任何值的時候,那么方法的類型是Unit。Unit唯一的一個實例是().


    from: http://www.aboutyun.com/thread-12224-1-1.html

    總結

    以上是生活随笔為你收集整理的Scala简明教程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。