Scalaクラス&オブジェクト(二)

5658 ワード

学習ノートTwitter scalaドキュメント:Twitter.github.io便宜上、本明細書のクラスの定義コードと呼び出しコードは同じ場所に置かれる.実際,コードの呼び出しはプログラムエントリ(mainメソッド)next:Scala集合に書く必要がある.
一、apply方法
クラスやオブジェクトに主な用途がある場合、applyメソッドはあなたに良い文法糖を提供します.
class Foo {}
object FooMaker {
  def apply() = new Foo
}

val newFoo = FooMaker() //       FooMaker  apply  

classでapplyメソッドを定義し、そのclassのオブジェクトを新規作成することで呼び出すことができます.
class Bar {
   def apply() = 0
}

val bar = new Bar
val res = bar()  //return 0;          apply  

二、一例オブジェクトObject
Objects are used to hold single instances of a class. Often used for factories.
Objectの定義
object Timer {
  var count = 0

  def currentCount(): Long = {
    count += 1
    count
  }
}

単一のオブジェクトは、クラスと同じ名前を持つことができます.この場合、オブジェクトは「伴生オブジェクト」とも呼ばれます.我々は通常、伴生オブジェクトを工場として使用します.
class Bar(foo: String)

object Bar {
  def apply(foo: String) = new Bar(foo)
}

val bar = Bar("Hello world")

三、Functions are Objects(関数は対象)
関数はいくつかの特質traitの集合です.具体的には、パラメータを持つ関数はFunction 1の特質の一例である.この特徴はapply()構文糖を定義し、オブジェクトを呼び出すときに関数を呼び出すようにします.
object addOne extends Function1[Int, Int] {
  def apply(m: Int): Int = m + 1
 }

addOne(2) //  3

Function 1特質のソース:
package scala
@scala.annotation.implicitNotFound("No implicit view available from ${T1} => ${R}.")
trait Function1[@scala.specialized -T1, @scala.specialized +R] extends scala.AnyRef {
  def apply(v1 : T1) : R
  @scala.annotation.unspecialized
  def compose[A](g : scala.Function1[A, T1]) : scala.Function1[A, R] = { /* compiled code */ }
  @scala.annotation.unspecialized
  def andThen[A](g : scala.Function1[R, A]) : scala.Function1[T1, A] = { /* compiled code */ }
  override def toString() : java.lang.String = { /* compiled code */ }
}
  • このFunction特質集合の下標は0から22
  • まで続く.
  • apply構文糖は、オブジェクトと関数プログラミングの二重性を統一するのに役立つ.クラスを渡して関数として使用することができますが、関数は本質的にクラスのインスタンス
  • です.
  • クラスで定義された方法は、関数クラスではなくメソッドであり、Functionを拡張することもでき、これらのクラスのインスタンスは()呼び出しを使用することができる.
  • class AddOne extends Function1[Int, Int] {
      def apply(m: Int): Int = m + 1
    }
    
    val plusOne = new AddOne()
    plusOne(2) //      +             apply  
    

    extends Function 1[Int,Int]の代わりに、より直感的で迅速なextends(Int=>Int)を使用できます.
    class AddOne extends (Int => Int) {
      def apply(m: Int): Int = m + 1
    }
    

    四、パッケージ
    package com.twitter.example
    

    値と関数は、クラスまたは単一のオブジェクトの外で定義できません.単一のオブジェクトは、静的関数(static function)を組織する有効なツールです.
    package com.twitter.example
    
    object colorHolder {
      val BLUE = "Blue"
      val RED = "Red"
    }
    
    println("the color is: " + com.twitter.example.colorHolder.BLUE)
    

    五、パターンマッチング(Pattern Matching)
    Matching on values
    val times = 1
    
    times match {
      case 1 => "one"
      case 2 => "two"
      case i if i == 3 => "three"
      case _ => "some other number"
    }
    
  • 最後の行の命令の中の_ワイルドカードです.それは私たちがすべての状況を処理できることを保証します.そうでなければ、一致しない数字が伝わると、実行時エラーが表示されます.
  • は順番に一致し、一致すると
  • に戻る.
    Matching on type
    def bigger(o: Any): Any = {
      o match {
        case i: Int if i < 0 => i - 1
        case i: Int => i + 1
        case d: Double if d < 0.0 => d - 0.1
        case d: Double => d + 0.1
        case text: String => text + "s"
        case _ => "unknown"
      }
    }
    

    Matching on class members
    def calcType(calc: Calculator) = calc match {
      case _ if calc.brand == "HP" && calc.model == "20B" => "financial"
      case _ if calc.brand == "HP" && calc.model == "48G" => "scientific"
      case _ if calc.brand == "HP" && calc.model == "30B" => "business"
      case _ => "unknown"
    }
    

    ああ、苦しい.幸いなことに、Scalaはこのような状況に対応する有効なツールを提供しています.サンプルクラスです.
    六、サンプル類(Case Classes)
    case classes are used to conveniently store and match on the contents of a class. You can construct them without using new.
  • このクラスの伴生オブジェクトを実装し、newキーワードを使用せずに対応するオブジェクト
  • を構築できるように、伴生オブジェクトにapplyメソッドを提供します.
  • 伴生オブジェクトにunapplyメソッドを提供するモードマッチングを
  • で動作させる.
  • サンプルクラスパラメータリスト内のすべてのパラメータは暗黙的にval接頭辞を取得するので、それらはフィールドメンテナンス
  • として扱われる.
  • toString、hashCode、equals、copyを追加した「ナチュラル」
  • を実現
    case class Calculator(brand: String, model: String)
    
    val hp20b = Calculator("HP", "20b")
    val hp20B = Calculator("HP", "20b")
    def calcType(calc: Calculator) = calc match {
      case Calculator("HP", "20B") => "financial"
      case Calculator("HP", "48G") => "scientific"
      case Calculator("HP", "30B") => "business"
      case Calculator(ourBrand, ourModel) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel)
    }
    

    最後の一言もこのように書くことができます
    case Calculator(_, _) => "Calculator of unknown type"
    case _ => "Calculator of unknown type"
    case c@Calculator(_, _) => "Calculator: %s of unknown type".format(c)
    

    七、異常(Exceptions)
    Scalaの例外はtry-catch-finally構文でパターンマッチングで使用できます
    try {
      remoteCalculatorService.add(1, 2)
    } catch {
      case e: ServerIsDownException => log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.")
      case e: IoException => log.error(e, "io error")
    } finally {
      remoteCalculatorService.close()
    }
    

    next:Scala集合