복붙노트

[SCALA] 스칼라 대 발-변경할 수 VAR-불변

SCALA

스칼라 대 발-변경할 수 VAR-불변

불변의 컬렉션 VAR를 사용하여 대 가변 컬렉션 발을 사용하는 경우에 스칼라에서 어떤 지침이 있습니까? 또는 당신은 정말 불변의 컬렉션 발을 목표로해야합니까?

모음의 두 가지 유형이 있다는 사실은 나에게 많은 선택을 제공하고, 자주하지 않습니다 그 선택을하는 방법을 알고있다.

해결법

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

    1.꽤 자주있는 질문이 하나. 하드 것은 중복을 찾는 것입니다.

    꽤 자주있는 질문이 하나. 하드 것은 중복을 찾는 것입니다.

    당신은 참조 투명성을 위해 노력한다. 무슨 의미하는 것은 내가 표현 "E"가 있다면, 나는 발 X = 전자를 만들고, X와 전자를 대체 할 수 있다는 것입니다. 이 가변성 휴식 그 속성입니다. 당신이 설계 결정을해야 할 때마다, 참조 투명성 극대화 할 수 있습니다.

    실제적인 문제로서, 방법 로컬 VAR는 방법을 탈출하지 않기 때문에, 존재하는 가장 안전한 VAR입니다. 방법은 더 나은, 짧은 경우. 그렇지 않을 경우에는 다른 방법을 추출하여 그것을 줄이기 위해 시도합니다.

    반면에, 변경 가능한 컬렉션 그렇지 않은 경우에도, 탈출 할 수있는 가능성이있다. 코드를 변경하는 경우, 당신은 다른 방법으로 전달하려는, 또는 그것을 반환 할 수 있습니다. 즉 참조 투명성을 나누기 물건의 종류입니다.

    객체 (필드)에서 거의 같은 일을하지만, 더 무서운 결과로 발생합니다. 어느 쪽이든 객체 참조 투명성을 깰 따라서 상태를 가지고 있습니다. 그러나 변경 가능한 콜렉션을 가지고 심지어 객체 자체가 변화 누가의 제어가 손실 될 수 있습니다 의미합니다.

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

    2.당신은 불변의 컬렉션과 함께 일을하고 당신이 그들을 "수정"해야하는 경우, 예를 들어, 당신은 당신이 어딘가에 결과 수집을 저장해야하기 때문에 바르를 사용해야합니다, 루프에서 그들에 요소를 추가 할 수 있습니다. 당신은 단지 불변의 컬렉션을 읽을 경우, 발스을 사용합니다.

    당신은 불변의 컬렉션과 함께 일을하고 당신이 그들을 "수정"해야하는 경우, 예를 들어, 당신은 당신이 어딘가에 결과 수집을 저장해야하기 때문에 바르를 사용해야합니다, 루프에서 그들에 요소를 추가 할 수 있습니다. 당신은 단지 불변의 컬렉션을 읽을 경우, 발스을 사용합니다.

    일반적으로, 당신은 참조와 개체를 혼동하지 않도록해야합니다. 발스 참조 불변 (C 상수 포인터)이다. 즉, 발 X = 새로운 MutableFoo ()를 사용할 때, 당신은에 포인트를 X 개체를 변경할 수 있습니다,하지만 당신은 X 점 오브젝트되는 변경할 수 없습니다입니다. 당신은 () VAR X = 새로운 ImmutableFoo을 사용하는 경우 반대 보유하고 있습니다. 내 초기 조언을 따기 : 당신이 기준점을 반대하는 놈들을 사용하려면 변경할 필요가없는 경우.

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

    3.이 답변을하는 가장 좋은 방법은 예제입니다. 우리는 어떤 프로세스가 단순히 어떤 이유로 번호를 수집 있다고 가정하자. 우리는이 숫자를 기록하고자하는, 그리고이 일을 다른 프로세스에 컬렉션을 보내드립니다.

    이 답변을하는 가장 좋은 방법은 예제입니다. 우리는 어떤 프로세스가 단순히 어떤 이유로 번호를 수집 있다고 가정하자. 우리는이 숫자를 기록하고자하는, 그리고이 일을 다른 프로세스에 컬렉션을 보내드립니다.

    우리가 로거 컬렉션을 보낸 후 물론, 우리는 여전히 번호를 수집하고 있습니다. 그리고의 실제 로깅을 지연 로깅 과정에서 약간의 오버 헤드가 가정 해 봅시다. 이 어디로 희망 당신은 볼 수 있습니다.

    우리가 변경 가능한 발에이 컬렉션을 저장하는 경우 (우리가 지속적으로에 추가되기 때문에 변경 가능)는,이 로깅을 수행하는 과정은 여전히 ​​우리의 수집 과정에서 업데이트되고있는 동일한 개체를보고된다는 것을 의미합니다. 그 콜렉션은 언제든지 업데이트 할 수 있으며, 그래서 우리가 실제로 우리가 보낸 컬렉션을 기록 할 수 없습니다 로그온하는 데 시간 때.

    우리는 불변의 VAR를 사용하는 경우, 우리는 로거 불변의 데이터 구조를 보낼 수 있습니다. 우리가 우리의 컬렉션에 더 많은 번호를 추가 할 때, 우리는 새로운 불변의 데이터 구조와 함께 우리의 VAR을 교체됩니다. 로거로 전송이 의미하는 것은 아니다 컬렉션 교체! 그것은 여전히 ​​보낸 컬렉션을 참조 할 것. 그래서 우리 로거는 실제로는 수신 컬렉션을 기록합니다.

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

    4.불변의 중요성을 동시성 :이 블로그 게시물의 예는 동시성 시나리오가된다 훨씬 더 중요한 사용하는 콤보있는 문제로, 더 많은 빛을 흘렸다 것이라 생각합니다. 우리가 그것에 인 동안, AtomicReference 같은 대 @volatile 대 동기화의 적절한 사용에주의 : 세 가지 도구를

    불변의 중요성을 동시성 :이 블로그 게시물의 예는 동시성 시나리오가된다 훨씬 더 중요한 사용하는 콤보있는 문제로, 더 많은 빛을 흘렸다 것이라 생각합니다. 우리가 그것에 인 동안, AtomicReference 같은 대 @volatile 대 동기화의 적절한 사용에주의 : 세 가지 도구를

  5. ==============================

    5.VAR 불변 대에 발 가변에게

    VAR 불변 대에 발 가변에게

    이 질문에 많은 훌륭한 답변에 추가. 다음은 간단한 예이고, 즉, 발 가변의 잠재적 인 위험을 보여

    재 할당이 허용되지 않은 상태에서 변경 가능한 객체는 매개 변수로 받아 방법, 내부에 수정 될 수 있습니다.

    import scala.collection.mutable.ArrayBuffer
    
    object MyObject {
        def main(args: Array[String]) {
    
            val a = ArrayBuffer(1,2,3,4)
            silly(a)
            println(a) // a has been modified here
        }
    
        def silly(a: ArrayBuffer[Int]): Unit = {
            a += 10
            println(s"length: ${a.length}")
        }
    }
    

    결과:

    length: 5
    ArrayBuffer(1, 2, 3, 4, 10)
    

    재 할당이 허용되지 않기 때문에 이런 식으로 뭔가가, VAR 불변 일어날 수 없습니다

    object MyObject {
        def main(args: Array[String]) {
            var v = Vector(1,2,3,4)
            silly(v)
            println(v)
        }
    
        def silly(v: Vector[Int]): Unit = {
            v = v :+ 10 // This line is not valid
            println(s"length of v: ${v.length}")
        }
    }
    

    결과 :

    error: reassignment to val
    

    함수 파라미터 브로로서 취급되기 때문에이 재 할당은 허용되지 않는다.

  6. from https://stackoverflow.com/questions/11386559/val-mutable-versus-var-immutable-in-scala by cc-by-sa and MIT license