복붙노트

[SCALA] 스칼라리스트 연결, ::: ++ 대

SCALA

스칼라리스트 연결, ::: ++ 대

어떤 차이가 사이 ::: 및 ++ 스칼라의 목록을 연결하기위한 있습니까?

scala> List(1,2,3) ++ List(4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)

scala> List(1,2,3) ::: List(4,5)
res1: List[Int] = List(1, 2, 3, 4, 5)

scala> res0 == res1
res2: Boolean = true

++ 목록 특정 반면 ::: 더 일반적인처럼 문서에서이 보인다. 그것은 다른 기능 언어로 사용 있기 때문에 후자가 제공되어 있습니까?

해결법

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

    1.유산. 목록은 원래 기능 - 언어적인 것으로 정의 하였다 :

    유산. 목록은 원래 기능 - 언어적인 것으로 정의 하였다 :

    1 :: 2 :: Nil // a list
    list1 ::: list2  // concatenation of two lists
    
    list match {
      case head :: tail => "non-empty"
      case Nil          => "empty"
    }
    

    물론, 스칼라는 애드혹 방식으로, 다른 컬렉션을 진화. 심지어 반복자 - 2.8이 나왔을 때, 컬렉션 당신은 두 컬렉션을 연결하는 ++ 사용할 수 있도록, 최대 코드를 재사용하고 일관된 API 재 설계되었다. 목록은, 그러나, 하나되지있어 둘을 제외하고, 원래의 운영을 유지하기 위해 얻었다.

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

    2.::: ++ 어떤에 이동과 함께 사용할 수있는 반면, 목록에만 작동합니다. 현재 구현 (2.9.0)에서 ++ 다시 떨어질 ::: 인수도 목록 경우.

    ::: ++ 어떤에 이동과 함께 사용할 수있는 반면, 목록에만 작동합니다. 현재 구현 (2.9.0)에서 ++ 다시 떨어질 ::: 인수도 목록 경우.

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

    3.항상 사용 :::. 효율성과 유형 안전 : 두 가지 이유가 있습니다.

    항상 사용 :::. 효율성과 유형 안전 : 두 가지 이유가 있습니다.

    능률

    오른쪽 연관이 있기 때문에 X ::: ::: ::: Y, Z는, X, Y ++ ++ Z보다 빠르다. X | |) ::: X, Y, Z는 ::: 알고리즘보다 빠른 인 X ::: (Y ::: z)로서 해석된다 (X, Y :::) ::: Z는 (후자 (O를 필요 더 많은 단계).

    유형 안전

    :::하면 두 개의 목록을 연결할 수 있습니다. 당신이 끔찍한 목록 어떤 모음을 추가 할 수 있습니다 ++로 :

    scala> List(1, 2, 3) ++ "ab"
    res0: List[AnyVal] = List(1, 2, 3, a, b)
    

    + + +와 섞어도 간단합니다 :

    scala> List(1, 2, 3) + "ab"
    res1: String = List(1, 2, 3)ab
    
  4. ==============================

    4.다른 점은 첫 번째 문장은 다음과 같이 해석됩니다입니다 :

    다른 점은 첫 번째 문장은 다음과 같이 해석됩니다입니다 :

    scala> List(1,2,3).++(List(4,5))
    res0: List[Int] = List(1, 2, 3, 4, 5)
    

    두 번째 예로서 해석되는 반면 :

    scala> List(4,5).:::(List(1,2,3))
    res1: List[Int] = List(1, 2, 3, 4, 5)
    

    당신이 매크로를 사용하는 경우 그래서, 당신은주의해야합니다.

    게다가, ++이 개 목록에 대한이 호출 :::하지만 더 오버 헤드가 나열하는 목록에서 빌더를 가지고 암시 적 값을 요구하고 있기 때문이다. 그러나 microbenchmarks는 그런 의미에서 유용 아무것도 증명하지 않았다, 내가 컴파일러는 호출을 최적화하는 것이 같아요.

    워밍업 후 마이크로 벤치 마크.

    scala>def time(a: => Unit): Long = { val t = System.currentTimeMillis; a; System.currentTimeMillis - t}
    scala>def average(a: () => Long) = (for(i<-1 to 100) yield a()).sum/100
    
    scala>average (() => time { (List[Int]() /: (1 to 1000)) { case (l, e) => l ++ List(e) } })
    res1: Long = 46
    scala>average (() => time { (List[Int]() /: (1 to 1000)) { case (l, e) => l ::: List(e ) } })
    res2: Long = 46
    

    다니엘 C. Sobrai 말했듯이, 당신은 목록을 연결할 수 있습니다 :::와 반면 ++ 사용하여 목록에 대한 수집의 내용을 추가 할 수 있습니다.

  5. from https://stackoverflow.com/questions/6559996/scala-list-concatenation-vs by cc-by-sa and MIT license