복붙노트

[SCALA] 스칼라의 숨겨진 기능

SCALA

스칼라의 숨겨진 기능

모든 스칼라 개발자가 알아야 할 것을 스칼라의 숨겨진 기능은 무엇입니까?

답변을 당 하나 개의 숨겨진 기능하시기 바랍니다.

해결법

  1. ==============================

    1.좋아, 내가 하나 더 추가했다. 스칼라의 모든 정규식 객체는 경기 그룹에 액세스 할 수 있습니다 추출기 (위 oxbox_lakes에서 답을 참조)이있다. 그래서 당신이 뭔가를 같이 할 수 있습니다 :

    좋아, 내가 하나 더 추가했다. 스칼라의 모든 정규식 객체는 경기 그룹에 액세스 할 수 있습니다 추출기 (위 oxbox_lakes에서 답을 참조)이있다. 그래서 당신이 뭔가를 같이 할 수 있습니다 :

    // Regex to split a date in the format Y/M/D.
    val regex = "(\\d+)/(\\d+)/(\\d+)".r
    val regex(year, month, day) = "2010/1/13"
    

    당신이 패턴 매칭 및 추출기를 사용하여 사용하지 않는 경우 두 번째 줄은 혼란 보인다. 당신이 발 또는 VAR을 정의 할 때마다, 어떤 키워드 다음에 오는 것은 단순히 오히려 식별자하지만 패턴이 아니다. 이 작품 이유 :

    val (a, b, c) = (1, 3.14159, "Hello, world")
    

    오른손 식은 Tuple3 [INT, 더블, 문자열] 패턴과 일치 할 수 생성 (A, B, C).

    대부분의 시간을 당신의 패턴은 단일 객체의 멤버 인 추출기를 사용합니다. 예를 들어, 같은 패턴을 작성하는 경우

    Some(value)
    

    당신은 암시 적으로 Some.unapply 추출기를 호출하고 있습니다.

    그러나 당신은 또한 패턴의 클래스 인스턴스를 사용할 수 있습니다, 그리고 여기에 무슨 일이 일어나고있다. 발 정규식은 정규식의 인스턴스이며, 당신이 패턴을 사용할 때, 당신은 암시 적으로 regex.unapplySeq를 호출하고 서열 [문자열]에 일치하는 그룹을 추출, (적용 취소 unapplySeq이 응답의 범위를 벗어 대) 의 요소는 변수의 년, 월, 일하기 위해 할당됩니다.

  2. ==============================

    2.타입 정의 구조 - 즉, 그것이 지원하는 방법에 의해 설명 된 타입. 예를 들면 :

    타입 정의 구조 - 즉, 그것이 지원하는 방법에 의해 설명 된 타입. 예를 들면 :

    object Closer {
        def using(closeable: { def close(): Unit }, f: => Unit) {
          try { 
            f
          } finally { closeable.close }
        }
    }
    

    그것은 근접 메소드가보다 닫혀 파라미터의 종류가 다른 정의되지 않은 것을 알

  3. ==============================

    3.이 기능이 없다면 당신은, 예를 들어, 다른 목록을 반환 목록을 통해 기능을 매핑, 또는 다른 나무를 반환하는 나무를 통해 기능을 매핑의 생각을 표현할 수 있습니다. 하지만 당신은 높은 가지 않고 일반적으로이 아이디어를 표현할 수 없습니다.

    이 기능이 없다면 당신은, 예를 들어, 다른 목록을 반환 목록을 통해 기능을 매핑, 또는 다른 나무를 반환하는 나무를 통해 기능을 매핑의 생각을 표현할 수 있습니다. 하지만 당신은 높은 가지 않고 일반적으로이 아이디어를 표현할 수 없습니다.

    높은 종류로, 당신은 다른 유형의 매개 변수화있어 모든 종류의 아이디어를 캡처 할 수 있습니다. (-> *) 하나 개의 파라미터를 취하는 타입 생성자 종류의 것으로 알려졌다. 예를 들어, 목록. 다른 종류의 생성자를 반환하는 타입의 생성자는 종류 (-> * -> * *)의 수라고합니다. 예를 들어, 기능 1. 그러나 스칼라, 우리는 더 높은 종류가있다, 그래서 우리는 다른 종류의 생성자에 매개 변수화하는 타입 생성자를 가질 수 있습니다. (> * - -> *) * () 그래서 그들은 같은 종류의 것.

    예를 들면 :

    trait Functor[F[_]] {
      def fmap[A, B](f: A => B, fa: F[A]): F[B]
    }
    

    이제, 당신이 펑터 [목록]이있는 경우, 당신은 목록을 통해 매핑 할 수 있습니다. 당신이 펑터 [트리]이 있다면, 당신은 나무를 통해 매핑 할 수 있습니다. 당신이 종류의 A의은 Functor [A]를해야하지만 더 중요한 것은, (* -> *), 당신은 A. 이상의 기능을 매핑 할 수 있습니다

  4. ==============================

    4.당신이 패턴 지저분한 ELSEIF 경우 --다른 스타일의 코드를 대체 할 수 추출기. 나는이 정확히 숨겨지지 않습니다 것을 알고 있지만 난 정말 그들의 힘을 이해하지 않고 몇 달 동안 스칼라를 사용하고있다. (긴) 예를 들어 나는 대체 할 수있다 :

    당신이 패턴 지저분한 ELSEIF 경우 --다른 스타일의 코드를 대체 할 수 추출기. 나는이 정확히 숨겨지지 않습니다 것을 알고 있지만 난 정말 그들의 힘을 이해하지 않고 몇 달 동안 스칼라를 사용하고있다. (긴) 예를 들어 나는 대체 할 수있다 :

    val code: String = ...
    val ps: ProductService = ...
    var p: Product = null
    if (code.endsWith("=")) {
      p = ps.findCash(code.substring(0, 3)) //e.g. USD=, GBP= etc
    }
    else if (code.endsWith(".FWD")) {
      //e.g. GBP20090625.FWD
      p = ps.findForward(code.substring(0,3), code.substring(3, 9))
    }
    else {
      p = ps.lookupProductByRic(code)
    }
    

    내 의견으로는 훨씬 명확하다이,로

    implicit val ps: ProductService = ...
    val p = code match {
      case SyntheticCodes.Cash(c) => c
      case SyntheticCodes.Forward(f) => f
      case _ => ps.lookupProductByRic(code)
    }
    

    나는 백그라운드에서 마술의 조금을 할 필요가 ...

    object SyntheticCodes {
      // Synthetic Code for a CashProduct
      object Cash extends (CashProduct => String) {
        def apply(p: CashProduct) = p.currency.name + "="
    
        //EXTRACTOR
        def unapply(s: String)(implicit ps: ProductService): Option[CashProduct] = {
          if (s.endsWith("=") 
            Some(ps.findCash(s.substring(0,3))) 
          else None
        }
      }
      //Synthetic Code for a ForwardProduct
      object Forward extends (ForwardProduct => String) {
        def apply(p: ForwardProduct) = p.currency.name + p.date.toString + ".FWD"
    
        //EXTRACTOR
        def unapply(s: String)(implicit ps: ProductService): Option[ForwardProduct] = {
          if (s.endsWith(".FWD") 
            Some(ps.findForward(s.substring(0,3), s.substring(3, 9)) 
          else None
        }
      }
    

    그러나 취재는 재치있는 장소로 비즈니스 로직의 일부를 분리한다는 사실에 대한 가치가있다. 다음과 같이 내 Product.getCode 방법을 구현할 수 있습니다 ..

    class CashProduct {
      def getCode = SyntheticCodes.Cash(this)
    }
    
    class ForwardProduct {
      def getCode = SyntheticCodes.Forward(this)     
    }
    
  5. ==============================

    5.스칼라 유형을 구체화 것처럼하는 매니페스트는 런타임에 유형 정보를 얻기에 방법의 일종이다.

    스칼라 유형을 구체화 것처럼하는 매니페스트는 런타임에 유형 정보를 얻기에 방법의 일종이다.

  6. ==============================

    6.스칼라 2.8에서는 패키지 scala.util.control.TailCalls을 (실제로는 트램펄린입니다)를 사용하여 꼬리 재귀 적 방법을 가질 수 있습니다.

    스칼라 2.8에서는 패키지 scala.util.control.TailCalls을 (실제로는 트램펄린입니다)를 사용하여 꼬리 재귀 적 방법을 가질 수 있습니다.

    예 :

    def u(n:Int):TailRec[Int] = {
      if (n==0) done(1)
      else tailcall(v(n/2))
    }
    def v(n:Int):TailRec[Int] = {
      if (n==0) done(5)
      else tailcall(u(n-1))
    }
    val l=for(n<-0 to 5) yield (n,u(n).result,v(n).result)
    println(l)
    
  7. ==============================

    7.자동 반사없이 필드에 지정되지 않은, 인덱스 액세스를 제공, 제품의 특성을 믹스 인 케이스 클래스 :

    자동 반사없이 필드에 지정되지 않은, 인덱스 액세스를 제공, 제품의 특성을 믹스 인 케이스 클래스 :

    case class Person(name: String, age: Int)
    
    val p = Person("Aaron", 28)
    val name = p.productElement(0) // name = "Aaron": Any
    val age = p.productElement(1) // age = 28: Any
    val fields = p.productIterator.toList // fields = List[Any]("Aaron", 28)
    

    이 기능은 toString 메소드의 출력을 변경하는 간단한 방법을 제공합니다 :

    case class Person(name: String, age: Int) {
       override def productPrefix = "person: "
    }
    
    // prints "person: (Aaron,28)" instead of "Person(Aaron, 28)"
    println(Person("Aaron", 28)) 
    
  8. ==============================

    8.scalac -Xprint : 그것은 정확히 확실히에서 광고 기능을 숨겨,하지만 아니에요.

    scalac -Xprint : 그것은 정확히 확실히에서 광고 기능을 숨겨,하지만 아니에요.

    사용의 그림으로 다음과 같은 소스를 고려 :

    class A { "xx".r }
    

    scalac -Xprint으로이 컴파일 : TYPER의 출력 :

    package <empty> {
      class A extends java.lang.Object with ScalaObject {
        def this(): A = {
          A.super.this();
          ()
        };
        scala.this.Predef.augmentString("xx").r
      }
    }
    

    Predef.scala 존재 암시 데프 augmentString의 응용이다 공지 scala.this.Predef.augmentString ( "XX"). R.

    scalac -Xprint : <상> 일부 컴파일러 단계 이후 구문 트리를 인쇄합니다. 사용할 수있는 단계가 scalac -Xshow-단계 사용을 참조하십시오.

    이 무대 뒤에서 무슨 일이 일어나고 있는지 배울 수있는 좋은 방법입니다.

    함께 시도

    경우 클래스 X (A : INT, B : 문자열)

    타이 퍼 단계를 사용하는 것은 정말 얼마나 유용 느낌.

  9. ==============================

    9.당신은 당신의 자신의 제어 구조를 정의 할 수 있습니다. 그것은 정말 기능과 객체와 몇 가지 문법 설탕을, 그러나 그들은보고 진짜처럼 행동.

    당신은 당신의 자신의 제어 구조를 정의 할 수 있습니다. 그것은 정말 기능과 객체와 몇 가지 문법 설탕을, 그러나 그들은보고 진짜처럼 행동.

    예를 들어, 다음 코드 (COND)까지 해달라고 {...}하지 않는 한 (COND) 및 해달라고 {...}을 정의한다 :

    def dont(code: => Unit) = new DontCommand(code)
    
    class DontCommand(code: => Unit) {
      def unless(condition: => Boolean) =
        if (condition) code
    
      def until(condition: => Boolean) = {
        while (!condition) {}
        code
      }
    }
    

    이제 다음을 수행 할 수 있습니다 :

    /* This will only get executed if the condition is true */
    dont {
      println("Yep, 2 really is greater than 1.")
    } unless (2 > 1) 
    
    /* Just a helper function */
    var number = 0;
    def nextNumber() = {
      number += 1
      println(number)
      number
    }
    
    /* This will not be printed until the condition is met. */
    dont {
      println("Done counting to 5!")
    } until (nextNumber() == 5) 
    
  10. ==============================

    10.스칼라 2.8에 주석을 @switch :

    스칼라 2.8에 주석을 @switch :

    예:

    scala> val n = 3
    n: Int = 3
    
    scala> import annotation.switch
    import annotation.switch
    
    scala> val s = (n: @switch) match {
         |   case 3 => "Three"
         |   case _ => "NoThree"
         | }
    <console>:6: error: could not emit switch for @switch annotated match
           val s = (n: @switch) match {
    
  11. ==============================

    11.몰라이 정말 숨겨진, 그러나 나는 꽤 좋은 찾을 경우.

    몰라이 정말 숨겨진, 그러나 나는 꽤 좋은 찾을 경우.

    이 개 유형의 매개 변수를 Typeconstructors는 중위 표기법으로 쓸 수있다

    object Main {                                                                   
      class FooBar[A, B]
    
      def main(args: Array[String]): Unit = {
        var x: FooBar[Int, BigInt] = null
        var y: Int FooBar BigInt   = null
      }
    }
    
  12. ==============================

    12.스칼라 2.8 기본을 소개하고 스칼라 클래스를 구분하기 위해 추가하는 새로운 "복사"방법의 추가 가능하게 인수를 지명했다. 당신이 정의하는 경우 :

    스칼라 2.8 기본을 소개하고 스칼라 클래스를 구분하기 위해 추가하는 새로운 "복사"방법의 추가 가능하게 인수를 지명했다. 당신이 정의하는 경우 :

    case class Foo(a: Int, b: Int, c: Int, ... z:Int)
    

    당신은 당신이 말하는 단지 수 있습니다 만 다른 "N"값으로, 기존의 푸처럼 새로운 푸를 만들려면 :

    foo.copy(n = 3)
    
  13. ==============================

    13.스칼라 2.8에 당신은 당신의 일반적인 클래스 / 메소드에 @specialized 추가 할 수 있습니다. 이것은 (AnyVal 확장) 기본 형식의 클래스의 특별한 버전을 만들 및 취소 필요한 복싱 / 언 박싱의 비용을 절약 할 수 : 클래스 푸 [T를 @specialized] ...

    스칼라 2.8에 당신은 당신의 일반적인 클래스 / 메소드에 @specialized 추가 할 수 있습니다. 이것은 (AnyVal 확장) 기본 형식의 클래스의 특별한 버전을 만들 및 취소 필요한 복싱 / 언 박싱의 비용을 절약 할 수 : 클래스 푸 [T를 @specialized] ...

    당신은 AnyVals의 하위 집합을 선택할 수 있습니다 : 클래스 푸 [@specialized (INT, 불리언) T] ...

  14. ==============================

    14.언어를 확장. 난 항상 자바에서이 같은 것을 (하지 수)하고 싶었다. 하지만 스칼라에서 내가 할 수 있습니다 :

    언어를 확장. 난 항상 자바에서이 같은 것을 (하지 수)하고 싶었다. 하지만 스칼라에서 내가 할 수 있습니다 :

      def timed[T](thunk: => T) = {
        val t1 = System.nanoTime
        val ret = thunk
        val time = System.nanoTime - t1
        println("Executed in: " + time/1000000.0 + " millisec")
        ret
      }
    

    다음 쓰기 :

    val numbers = List(12, 42, 3, 11, 6, 3, 77, 44)
    val sorted = timed {   // "timed" is a new "keyword"!
      numbers.sortWith(_<_)
    }
    println(sorted)
    

    그리고 얻다

    Executed in: 6.410311 millisec
    List(3, 3, 6, 11, 12, 42, 44, 77)
    
  15. ==============================

    15.통화 별 이름 매개 변수 (! 편집 :이 다음 게으른 매개 변수 다릅니다) 지정할 수있는 기능을하고 함수에 의해 사용되는 때까지 평가되지 않습니다 (편집 : 사실, 그것은 그 때마다 재평가한다 익숙한). 자세한 내용은이 FAQ를 참조

    통화 별 이름 매개 변수 (! 편집 :이 다음 게으른 매개 변수 다릅니다) 지정할 수있는 기능을하고 함수에 의해 사용되는 때까지 평가되지 않습니다 (편집 : 사실, 그것은 그 때마다 재평가한다 익숙한). 자세한 내용은이 FAQ를 참조

    class Bar(i:Int) {
        println("constructing bar " + i)
        override def toString():String = {
            "bar with value: " + i
        }
    }
    
    // NOTE the => in the method declaration.  It indicates a lazy paramter
    def foo(x: => Bar) = {
        println("foo called")
        println("bar: " + x)
    }
    
    
    foo(new Bar(22))
    
    /*
    prints the following:
    foo called
    constructing bar 22
    bar with value: 22
    */
    
  16. ==============================

    16.당신은 세미콜론으로 추론 문제를 유발하지 않고 로컬 블록을 소개하는 로컬로 사용할 수 있습니다.

    당신은 세미콜론으로 추론 문제를 유발하지 않고 로컬 블록을 소개하는 로컬로 사용할 수 있습니다.

    용법:

    scala> case class Dog(name: String) {
         |   def bark() {
         |     println("Bow Vow")
         |   }
         | }
    defined class Dog
    
    scala> val d = Dog("Barnie")
    d: Dog = Dog(Barnie)
    
    scala> locally {
         |   import d._
         |   bark()
         |   bark()
         | }
    Bow Vow
    Bow Vow
    

    로컬로 "Predef.scala"에 정의되어 있습니다 :

    @inline def locally[T](x: T): T = x
    

    인라인이기 때문에, 그것은 추가적인 오버 헤드를 부과하지 않습니다.

  17. ==============================

    17.초기 초기화 :

    초기 초기화 :

    trait AbstractT2 {
      println("In AbstractT2:")
      val value: Int
      val inverse = 1.0/value
      println("AbstractT2: value = "+value+", inverse = "+inverse)
    }
    
    val c2c = new {
      // Only initializations are allowed in pre-init. blocks.
      // println("In c2c:")
      val value = 10
    } with AbstractT2
    
    println("c2c.value = "+c2c.value+", inverse = "+c2c.inverse)
    

    산출:

    In AbstractT2:  
    AbstractT2: value = 10, inverse = 0.1  
    c2c.value = 10, inverse = 0.1
    
  18. ==============================

    18.당신은 '과'키워드 구조 유형을 구성 할 수

    당신은 '과'키워드 구조 유형을 구성 할 수

    object Main {
      type A = {def foo: Unit}
      type B = {def bar: Unit}
    
      type C = A with B
    
      class myA {
        def foo: Unit = println("myA.foo")
      }
    
    
      class myB {
        def bar: Unit = println("myB.bar")
      }
      class myC extends myB {
        def foo: Unit = println("myC.foo")
      }
    
      def main(args: Array[String]): Unit = { 
        val a: A = new myA 
        a.foo
        val b: C = new myC 
        b.bar
        b.foo
      }
    }
    
  19. ==============================

    19.익명 함수에 대한 자리 표시 자 구문

    익명 함수에 대한 자리 표시 자 구문

    스칼라 언어 사양에서 :

    SimpleExpr1 ::= '_'
    

    스칼라 언어 변경에서 :

    _ + 1                  x => x + 1
    _ * _                  (x1, x2) => x1 * x2
    (_: Int) * 2           (x: Int) => x * 2
    if (_) x else y        z => if (z) x else y
    _.map(f)               x => x.map(f)
    _.map(_ + 1)           x => x.map(y => y + 1)
    

    이 사용 당신이 뭔가를 같이 할 수있는 :

    def filesEnding(query: String) =
      filesMatching(_.endsWith(query))
    
  20. ==============================

    20.암시 적 정의, 특히 변환.

    암시 적 정의, 특히 변환.

    예를 들어, 그것을 중간 대체함으로써, 크기에 맞게 입력 문자열을 포맷하는 함수를 추정 "..."

    def sizeBoundedString(s: String, n: Int): String = {
      if (n < 5 && n < s.length) throw new IllegalArgumentException
      if (s.length > n) {
        val trailLength = ((n - 3) / 2) min 3
        val headLength = n - 3 - trailLength
        s.substring(0, headLength)+"..."+s.substring(s.length - trailLength, s.length)
      } else s
    }
    

    당신은 무엇을 변환하는 toString 메소드를 사용 물론, 임의의 문자열로 그것을 사용하고 있습니다. 하지만이처럼 쓸 수있다 :

    def sizeBoundedString[T](s: T, n: Int)(implicit toStr: T => String): String = {
      if (n < 5 && n < s.length) throw new IllegalArgumentException
      if (s.length > n) {
        val trailLength = ((n - 3) / 2) min 3
        val headLength = n - 3 - trailLength
        s.substring(0, headLength)+"..."+s.substring(s.length - trailLength, s.length)
      } else s
    }
    

    그리고, 당신은이 작업을 수행하여 다른 종류의 클래스를 전달할 수 :

    implicit def double2String(d: Double) = d.toString
    

    지금 당신은 이중 전달이 함수를 호출 할 수 있습니다 :

    sizeBoundedString(12345.12345D, 8)
    

    마지막 인수는 암시 적이며, 때문에 암시 드 선언의 자동으로 전달되고있다. 그것으로부터 문자열로 암시 적 변환이 있기 때문에 또한, "S"안에 sizeBoundedString 문자열로 취급되고있다.

    이러한 유형의 Implicits 더 나은 예기치 않은 변환을 방지하기 위해 드문 유형에 대한 정의된다. 또한 명시 적 변환을 통과 할 수 있으며, 그것은 여전히 ​​암시 sizeBoundedString 내부에 사용됩니다 :

    sizeBoundedString(1234567890L, 8)((l : Long) => l.toString)
    

    또한 여러 암시 인수를 가질 수 있지만, 당신은 그들 중 하나를 통과 그들 모두에 합격하거나, 안 중 하나. 암시 적 변환에 대한 바로 가기 구문이있다 :

    def sizeBoundedString[T <% String](s: T, n: Int): String = {
      if (n < 5 && n < s.length) throw new IllegalArgumentException
      if (s.length > n) {
        val trailLength = ((n - 3) / 2) min 3
        val headLength = n - 3 - trailLength
        s.substring(0, headLength)+"..."+s.substring(s.length - trailLength, s.length)
      } else s
    }
    

    이 정확히 같은 방식으로 사용된다.

    Implicits 어떤 값을 가질 수 있습니다. 그들은 도서관 정보를 숨기기 위해, 예를 들어, 사용할 수 있습니다. 예를 들어, 다음의 예를 보자

    case class Daemon(name: String) {
      def log(msg: String) = println(name+": "+msg)
    }
    
    object DefaultDaemon extends Daemon("Default")
    
    trait Logger {
      private var logd: Option[Daemon] = None
      implicit def daemon: Daemon = logd getOrElse DefaultDaemon
    
      def logTo(daemon: Daemon) = 
        if (logd == None) logd = Some(daemon) 
        else throw new IllegalArgumentException
    
      def log(msg: String)(implicit daemon: Daemon) = daemon.log(msg)
    }
    
    class X extends Logger {
      logTo(Daemon("X Daemon"))
    
      def f = {
        log("f called")
        println("Stuff")
      }
    
      def g = {
        log("g called")(DefaultDaemon)
      }
    }
    
    class Y extends Logger {
      def f = {
        log("f called")
        println("Stuff")
      }
    }
    

    이 예에서는 Y 개체에서 "F"를 호출하면 기본 데몬에 로그를 전송하고, 데몬 X 데몬 X의 인스턴스에 대한 것입니다. 그러나 X의 인스턴스에 g를 호출하면 명시 적으로 부여 DefaultDaemon에 로그를 보낼 것입니다.

    이 간단한 예제는 과부하 및 개인 상태와 다시 기록 할 수 있지만, implicits 개인 상태를 필요로하지 않으며, 수입과 문맥하게 할 수있다.

  21. ==============================

    21.어쩌면 너무 숨겨진,하지만 난이 유용하다 생각하지 :

    어쩌면 너무 숨겨진,하지만 난이 유용하다 생각하지 :

    @scala.reflect.BeanProperty
    var firstName:String = _
    

    이것은 자동으로 빈 규칙을 일치하는 필드에 대한 getter와 setter를 생성합니다.

    또한, 설명에 대한 developerWorks

  22. ==============================

    22.폐쇄의 암시 적 인수.

    폐쇄의 암시 적 인수.

    함수 인수 단지 방법과 암시 적으로 표시 될 수있다. 암시 적 매개 변수가 암시 해상도 볼 수와 자격이 함수 본문의 범위 내에서 :

    trait Foo { def bar }
    
    trait Base {
      def callBar(implicit foo: Foo) = foo.bar
    }
    
    object Test extends Base {
      val f: Foo => Unit = { implicit foo =>
        callBar
      }
      def test = f(new Foo {
        def bar = println("Hello")
      })
    }
    
  23. ==============================

    23.스칼라의 스트림 무한 데이터 구조를 구축 : http://www.codecommit.com/blog/scala/infinite-lists-for-the-finitely-patient

    스칼라의 스트림 무한 데이터 구조를 구축 : http://www.codecommit.com/blog/scala/infinite-lists-for-the-finitely-patient

  24. ==============================

    24.결과 유형은 암시 적 해상도에 따라 달라집니다. 이렇게하면 여러 파견의 형태를 제공 할 수 있습니다 :

    결과 유형은 암시 적 해상도에 따라 달라집니다. 이렇게하면 여러 파견의 형태를 제공 할 수 있습니다 :

    scala> trait PerformFunc[A,B] { def perform(a : A) : B }
    defined trait PerformFunc
    
    scala> implicit val stringToInt = new PerformFunc[String,Int] {
      def perform(a : String)  = 5
    }
    stringToInt: java.lang.Object with PerformFunc[String,Int] = $anon$1@13ccf137
    
    scala> implicit val intToDouble = new PerformFunc[Int,Double] {
      def perform(a : Int) = 1.0
    }
    intToDouble: java.lang.Object with PerformFunc[Int,Double] = $anon$1@74e551a4
    
    scala> def foo[A, B](x : A)(implicit z : PerformFunc[A,B]) : B = z.perform(x)
    foo: [A,B](x: A)(implicit z: PerformFunc[A,B])B
    
    scala> foo("HAI")
    res16: Int = 5
    
    scala> foo(1)
    res17: Double = 1.0
    
  25. ==============================

    25.스칼라는 해당 클래스의 인스턴스를 초기화하는 문을 포함하는 클래스 (생성자)의 몸 익명의 하위 클래스를 만들 수 있습니다.

    스칼라는 해당 클래스의 인스턴스를 초기화하는 문을 포함하는 클래스 (생성자)의 몸 익명의 하위 클래스를 만들 수 있습니다.

    더 간결하게 그 특성을 UI 구성 요소를 생성하고 선언 할 수로 (예 스윙 angel이라는 경우) 컴포넌트 기반의 사용자 인터페이스를 구성 할 때이 패턴은 매우 유용하다.

    자세한 내용은 http://spot.colorado.edu/~reids/papers/how-scala-experience-improved-our-java-development-reid-2011.pdf를 참조하십시오.

    여기 angel이라는 버튼을 작성하는 예이다 :

    val button = new Button("Click me"){
     setWidth("20px")
     setDescription("Click on this")
     setIcon(new ThemeResource("icons/ok.png"))
    }
    
  26. ==============================

    26.당신이에 println과 printerr 방법을 포함하는 로거를 사용한다고 가정하지만, 당신은 단지 오류 메시지에 대한 하나를 사용하여 표준 출력에 대한 좋은 오래된 Predef.println을 유지하려는. 이 작업을 수행 할 수 있습니다 :

    당신이에 println과 printerr 방법을 포함하는 로거를 사용한다고 가정하지만, 당신은 단지 오류 메시지에 대한 하나를 사용하여 표준 출력에 대한 좋은 오래된 Predef.println을 유지하려는. 이 작업을 수행 할 수 있습니다 :

    val logger = new Logger(...)
    import logger.printerr
    

    로거는 또한 수입 및 사용하고자하는 다른 열두 방법을 포함하는 경우, 그것은을 나열하는 불편된다. 대신 시도해 볼 수도 있습니다 :

    import logger.{println => donotuseprintlnt, _}
    

    그러나 이것은 여전히 ​​수입 멤버의 목록을 "오염". 동네 짱 강력한 와일드 카드를 입력 :

    import logger.{println => _, _}
    

    그리고 그냥 옳은 일을 ™을 할 것입니다.

  27. ==============================

    27.당신은 런타임 동안 점검 할 것 부가 기능 제약을 정의 할 수 있습니다 (PREDEF에 정의) 방법을 필요로한다. 당신은 또 다른 트위터 클라이언트를 개발하고 당신이 140 개 문자로 트윗 길이를 제한 할 필요가 있다고 상상해보십시오. 또한 당신은 빈 트윗을 게시 할 수 없습니다.

    당신은 런타임 동안 점검 할 것 부가 기능 제약을 정의 할 수 있습니다 (PREDEF에 정의) 방법을 필요로한다. 당신은 또 다른 트위터 클라이언트를 개발하고 당신이 140 개 문자로 트윗 길이를 제한 할 필요가 있다고 상상해보십시오. 또한 당신은 빈 트윗을 게시 할 수 없습니다.

    def post(tweet: String) = {
      require(tweet.length < 140 && tweet.length > 0) 
      println(tweet)
     }
    

    이제 예외가 발생합니다 부적절 길이 인수 게시물을 호출 :

    scala> post("that's ok")
    that's ok
    
    scala> post("")
    java.lang.IllegalArgumentException: requirement failed
        at scala.Predef$.require(Predef.scala:145)
        at .post(<console>:8)
    
    scala> post("way to looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong tweet") 
    java.lang.IllegalArgumentException: requirement failed
        at scala.Predef$.require(Predef.scala:145)
        at .post(<console>:8)
    

    각에 설명을 추가 할 경우에도 여러 요구 사항을 작성하거나 할 수 있습니다 :

    def post(tweet: String) = {
      require(tweet.length > 0, "too short message")
      require(tweet.length < 140, "too long message")
      println(tweet)
    }
    

    이제 예외 자세한 있습니다 :

    scala> post("")
    java.lang.IllegalArgumentException: requirement failed: too short message
        at scala.Predef$.require(Predef.scala:157)
        at .post(<console>:8)
    

    또 하나의 예는 여기에있다.

    당신은 때마다 요구 사항이 실패하는 작업을 수행 할 수 있습니다 :

    scala> var errorcount = 0
    errorcount: Int = 0
    
    def post(tweet: String) = {
      require(tweet.length > 0, {errorcount+=1})
      println(tweet)
      }
    
    scala> errorcount
    res14: Int = 0
    
    scala> post("")
    java.lang.IllegalArgumentException: requirement failed: ()
        at scala.Predef$.require(Predef.scala:157)
        at .post(<console>:9)
    ...
    
    scala> errorcount
    res16: Int = 1
    
  28. ==============================

    28.추상적 인 재정의 방법과 특성은 널리 많은 사람들로 광고하지 않는 스칼라의 기능입니다. 추상 재정의 수정과 방법의하고자하는 것은 일부 작업을하고 슈퍼에 대한 호출을 위임하는 것입니다. 그리고 이러한 특성은 추상적 인 재정 방법의 구체적인 구현과 혼합에 있어야합니다.

    추상적 인 재정의 방법과 특성은 널리 많은 사람들로 광고하지 않는 스칼라의 기능입니다. 추상 재정의 수정과 방법의하고자하는 것은 일부 작업을하고 슈퍼에 대한 호출을 위임하는 것입니다. 그리고 이러한 특성은 추상적 인 재정 방법의 구체적인 구현과 혼합에 있어야합니다.

    trait A {
      def a(s : String) : String
    }
    
    trait TimingA extends A {
      abstract override def a(s : String) = {
        val start = System.currentTimeMillis
        val result = super.a(s)
        val dur = System.currentTimeMillis-start
        println("Executed a in %s ms".format(dur))
        result
      }
    }
    
    trait ParameterPrintingA extends A {
      abstract override def a(s : String) = {
        println("Called a with s=%s".format(s))
        super.a(s)
      }
    }
    
    trait ImplementingA extends A {
      def a(s: String) = s.reverse
    }
    
    scala> val a = new ImplementingA with TimingA with ParameterPrintingA
    
    scala> a.a("a lotta as")
    Called a with s=a lotta as
    Executed a in 0 ms
    res4: String = sa attol a
    

    내 예는 정말로 훨씬 더 가난한 망 AOP보다 동안, 나는 미리 정의 된 수입, 사용자 정의 바인딩 및 classpathes와 스칼라 인터프리터 인스턴스를 구축하는 것이 훨씬 내 취향에 이러한 스택 특성을 사용했다. 스택 형 형질은 가능한 유용한 수입이 있고 범위는 사용자 스크립트 varibles 다음 LuceneLibs와 JsonLibs 새로운 InterpreterFactory의 라인을 따라 내 공장을 생성하고했다.

  29. from https://stackoverflow.com/questions/1025181/hidden-features-of-scala by cc-by-sa and MIT license