복붙노트

[SCALA] 전용 [이] 전용 VS

SCALA

전용 [이] 전용 VS

스칼라에서 나는 개체 개인 변수 등의 기능을 참조하십시오. 내되지 매우 풍부한 자바 배경에서 나는 모든 (개인 그것을 확인) 및 필요한 경우 (접근을 제공) 개방을 닫습니다 배웠습니다. 스칼라 더욱 엄격한 액세스 한정자를 소개합니다. 나는 항상 기본적으로 사용할 수 있습니까? 아니면 그것은 단지 내가 명시 적으로 심지어 같은 클래스의 개체에 대한 필드 값을 변경 제한 할 필요가 일부 특정 경우에 사용해야합니까? 즉 나는 사이 방법을 선택해야합니다

class Dummy {
    private var name = "default name"
}

class Dummy {
    private[this] var name = "default name"
}

두 번째는 더 엄격하고 나는 그것을 좋아하지만 내가 강한 이유가있는 경우에만 나는 항상 그것을 사용하거나해야합니까?

편집 : "패키지, 클래스 또는 단일 개체를"내가 여기 [이] 그냥 subcase이며,이 대신에 내가 다른 수정을 사용할 수 있습니다 개인시피. 그래서 몇 가지 특별한 경우를 위해 떠날거야.

해결법

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

    1.나는 어떤 변화가 하나 개의 클래스 중 하나의 방법을 접촉하기 때문에 그것은 너무 많은 중요한 생각하지 않습니다. 적용되지 않습니다 공개를 통해 보호를 통해 그래서 가장 중요한 이유는 개인 선호합니다.

    나는 어떤 변화가 하나 개의 클래스 중 하나의 방법을 접촉하기 때문에 그것은 너무 많은 중요한 생각하지 않습니다. 적용되지 않습니다 공개를 통해 보호를 통해 그래서 가장 중요한 이유는 개인 선호합니다.

    개인 [이] (당신이 직접 필드 액세스 대신 방법이 방법을 얻을 것이기 때문에) 성능이 정말로 중요한 곳을 사용합니다. 이 속성이 개인이고 하나는 [이]를 개인 왜 사람들이 알아낼 필요가 없습니다 그렇지 않으면, 하나의 스타일에 정착.

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

    2.개인은 [이]이 코드를 컴파일을하기 위해 요구되는 경우가 있습니다. 이것은 분산 표기 및 변경 가능한 변수의 상호 작용과 관련이있다. 다음 (쓸모없는) 클래스를 고려 :

    개인은 [이]이 코드를 컴파일을하기 위해 요구되는 경우가 있습니다. 이것은 분산 표기 및 변경 가능한 변수의 상호 작용과 관련이있다. 다음 (쓸모없는) 클래스를 고려 :

    class Holder[+T] (initialValue: Option[T]) {
        // without [this] it will not compile
        private[this] var value = initialValue
    
        def getValue = value
        def makeEmpty { value = None }
    }
    

    그래서이 클래스는, 옵션 값을 보유 옵션으로 반환하고 값 (따라서 VAR)을 취소 makeEmpty를 호출하는 사용자 수 있도록 설계되었습니다. 언급 한 바와 같이 점을 입증를 제외하고,이 쓸모가 없다.

    대신 [이]는 다음과 같은 오류 메시지와 함께 실패합니다 개인 개인이 코드를 컴파일하려고하면 :

    값 [이] 프라이빗 인스턴스에 전용으로 표시되지 않는 한 일반적으로 문제가되는 공변 타입 T (T +)의 가변 변수이기 때문에 에러가 발생한다. 컴파일러는 분산의 특별한 취급이 특별한 경우를 처리하기 위해 확인했다.

    그래서 비전입니다하지만 [이] 개인을 통해 개인 요구되는 경우가있다.

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

    3.개인 VAR 이름 (및 동반자 더미 오브젝트) 클래스 더미의 방법에서 액세스 할 수 있습니다.

    개인 VAR 이름 (및 동반자 더미 오브젝트) 클래스 더미의 방법에서 액세스 할 수 있습니다.

    개인 [이] VAR의 이름은 클래스가 아닌 더미의 다른 개체에서이 개체의 메서드에서 액세스 할 수 있습니다.

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

    4.그래서 당신은 개인이 [이] 때마다 당신이 원하는 할 수 있지만 당신이 그것을 참조해야 할 경우 몇 가지 문제가있을 수 있습니다

    그래서 당신은 개인이 [이] 때마다 당신이 원하는 할 수 있지만 당신이 그것을 참조해야 할 경우 몇 가지 문제가있을 수 있습니다

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

    5.이는 스칼라 2.11.5를 사용하여 테스트했다. 아래 코드를 살펴 보자

    이는 스칼라 2.11.5를 사용하여 테스트했다. 아래 코드를 살펴 보자

    class C(private val x: Int) {
      override def equals(obj: Any) = obj match {
        case other: C => x == other.x
        case _ => false
      }
    }
    
    println(new C(5) == new C(5)) //true
    println(new C(5) == new C(4)) //false
    

    그것은 컴파일이 자바 (1.8) 코드로 작동합니다

    class C {
        private int x;
    
        public C(int x) {
            this.x = x;
        }
    
        public boolean equals(Object obj) {
            if (obj instanceof C) {
                return ((C) obj).x == x;
            }
            else {
                return false;
            }
        }
    }
    
    System.out.println(new C(5).equals(new C(5))); //true
    System.out.println(new C(5).equals(new C(4))); //false
    

    사용하지만 경우 '[이]'수정에게 아래 코드는 컴파일되지 않습니다

    class C(private[this] val x: Int) {
      override def equals(obj: Any) = obj match {
        case other: C => this.x == other.x //problem is here
        case _ => false
      }
    }
    

    이것은 첫 번째 경우에 'X'때문에 두 번째 경우보다 엄격한 인스턴스 수준이 그것입니다있는 반면, 클래스 수준에 액세스 할 수 있습니다. 그것이 속한 'X'는 예에서만 액세스 할 수있는 것을 의미한다. 그래서 'this.x는'미세하지만 'other.x'는 아니다.

    당신은 "스칼라 프로그래밍 : 종합 단계별 가이드"섹션 13.5을 참조 할 수 있습니다 책을 액세스 수정에 대한 자세한 내용은.

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

    6.개인 개질제 범위 추가하는 경우 (개인용 [X]을) 효과적으로 같이 동작 X 약간 바깥 쪽을 나타내고 X 패키지, 클래스 또는 단일 개체 "최대".

    개인 개질제 범위 추가하는 경우 (개인용 [X]을) 효과적으로 같이 동작 X 약간 바깥 쪽을 나타내고 X 패키지, 클래스 또는 단일 개체 "최대".

    예를 들어 바 패키지이며, 전용 [바는, 모든 클래스의 각 인스턴스는 개질제 제한 부재 중 액세스 할 바 패키지에 속하는 것을 의미한다.

    전용 [이]의 경우, 상기 부재는 각각의 인스턴스 만 액세스 할 수 있음을 의미한다. 이것은 다음의 예에서보다 명확해진다 :

    class Foo(foo:Foo){  
       private[this] val i = 2
       println(this.i + foo.i)
    }
    
    >>error: value i is not a member of Foo
    
    class Foo(foo:Foo){  
        private val i = 2
        println(this.i + foo.i)
    }
    
    >>defined class Foo
    

    당신이 볼 수 있듯이 모든 인스턴스가 개인 발에 난에 액세스 할 수 있기 때문에, 두 번째 푸 아무 문제가 없습니다. 각 인스턴스가 다른 인스턴스의 난을 볼 수 있기 때문에 첫 번째 푸에 오류가있다.

    그것은 더 큰 제한을 부과하기 때문에 민간 [이]를 작성하는 것이 좋습니다.

  7. ==============================

    7.자바와 같은 대부분의 OOP 프로그래밍 언어에서, 민간 분야 / 방법이 개인 필드 / 메소드는 클래스의 외부에서 액세스 할 수없는 것을 의미한다. 그러나 인스턴스 / 동일 클래스의 객체가 할당 연산자를 사용하여 오브젝트의 전용 필드 또는 복사 생성자에 의해 액세스 할 수있다. 스칼라에서 민간 [이] 객체입니다 같은 클래스의 다른 목적은 개인 [이] 멤버에 액세스 할 수 없습니다 있는지 확인하게하는 개인.

    자바와 같은 대부분의 OOP 프로그래밍 언어에서, 민간 분야 / 방법이 개인 필드 / 메소드는 클래스의 외부에서 액세스 할 수없는 것을 의미한다. 그러나 인스턴스 / 동일 클래스의 객체가 할당 연산자를 사용하여 오브젝트의 전용 필드 또는 복사 생성자에 의해 액세스 할 수있다. 스칼라에서 민간 [이] 객체입니다 같은 클래스의 다른 목적은 개인 [이] 멤버에 액세스 할 수 없습니다 있는지 확인하게하는 개인.

    전용 [이] 1.Without

    object ObjectPrivateDemo {
    
      def main(args: Array[String]) {
        var real = new User("realUserName", "realPassword")
        var guest = new User("dummyUserName", "dummyPassword")
        real.displayUser(guest)
    
      }
    }
    
    class User(val username:String,val password:String) {
      private var _username=username
      private var _password=password
    
    
    
      def displayUser(guest:User){
    
             println(" guest username="+guest._username+" guest password="+guest._password)
           guest._username= this._username
        guest._password=  this._password
           println(" guest username="+guest._username+" guest password="+guest._password)
    
    
      }
    }
    

    2.Using 전용 [이]

    class User(val username: String, val password: String) {
      private var _username = username
      private[this] var _password = password
    
    
    
      def displayUser(guest: User) {
    
        println(this._username)
        println(this._password)
    
        guest._username = this._username
        // for guest._password it will give this :error  value _password is not member of class User
        guest._password = this._password
    
      }
    }
    

    따라서 민간 [이] _password 필드이 만 액세스 할 수 있는지 확인합니다.

  8. ==============================

    8.알렉세이 로마노프가 언급 한 성능 문제에 대해 자세히 설명하기 위해, 여기 내 추측의 일부입니다. 책에서 인용 "스칼라 프로그래밍 : 종합 단계별 가이드, 제 2 판"섹션 18.2 :

    알렉세이 로마노프가 언급 한 성능 문제에 대해 자세히 설명하기 위해, 여기 내 추측의 일부입니다. 책에서 인용 "스칼라 프로그래밍 : 종합 단계별 가이드, 제 2 판"섹션 18.2 :

    그것을 테스트하기 위해이 코드는 컴파일 오류가 발생합니다 :

    class PrivateTest{
      var data: Int = 0
      def data_=(x : Int){
        require(x > 0)
        data = x
      }
    }
    

    스칼라는 오류에 대한 불평 : 오버로드 정의에 대한 모호한 참조. data_ =에 override 키워드를 추가하는 방법이 컴파일러에 의해 생성되는 것을 증명해야 도움이되지 않습니다. 변수 데이터에 개인 키워드를 추가하면 여전히 컴파일 오류가 발생합니다. 그러나, 다음 코드는 잘 컴파일 :

    class PrivateTest{
      private[this] var data: Int = 0
      def data_=(x : Int){
        require(x > 0)
        data = x
      }
    }
    

    그래서, 전용 [이것은] 게터와 세터 방법에서 스칼라 생성을 방지 같다. 따라서, 이러한 변수를 액세스하는 게터와 세터 메소드 호출의 오버 헤드가 저장된다.

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

    9.그것은 개인 사용하는 것이 좋습니다 [이] 당신이 변수를 동기화하려는 경우.

    그것은 개인 사용하는 것이 좋습니다 [이] 당신이 변수를 동기화하려는 경우.

    스파크 팀의 스칼라 스타일 가이드에서 여기 좋은 예 :

    // The following is still unsafe.
    class Foo {
      private var count: Int = 0
      def inc(): Unit = synchronized { count += 1 }
    }
    
    // The following is safe.
    class Foo {
      private[this] var count: Int = 0
      def inc(): Unit = synchronized { count += 1 }
    }
    
  10. from https://stackoverflow.com/questions/9698677/privatethis-vs-private by cc-by-sa and MIT license