Groovy 클립:this,owner,delegate(규격 파일 선택 번역)

9886 단어
Groovy의 사양 파일을 번역하는 3.2 Owner, delegate and this

3.2. Owner, delegate and this


delegate의 개념을 이해하기 위해서, 우리는 먼저 패키지에서 키워드인this의 의미를 명확하게 설명해야 한다.클립은 일반적으로 세 개의 양을 정의한다.
  • this는 패키지 정의가 있는 클래스를 가리킨다
  • owner는 패키지 정의가 있는 대상을 가리키는데 이 대상은 클래스일 수도 있고 다른 패키지일 수도 있다.[클립은 정의를 삽입할 수 있기 때문이다.]
  • delegate는 제3자의 (위탁) 대상을 가리키며 클로즈업에서 호출하는 방법이나 속성이 정의되지 않을 때 위탁 대상에서 찾는다.

  • 3.2.1. this의 의미


    패키지에서 호출 getThisObject 은 이 패키지가 정의한 대상을 되돌려줍니다.그것은 하나의 현식this을 사용하는 것과 같다.
    class Enclosing {
        void run() {
            def whatIsThisObject = { getThisObject() }  //#1 
            assert whatIsThisObject() == this           //#2
            def whatIsThis = { this }                           //#3
            assert whatIsThis() == this                        //#4 
        }
    }
    class EnclosedInInnerClass {
        class Inner {
            Closure cl = { this }                               //#5
        }
        void run() {
            def inner = new Inner()
            assert inner.cl() == inner                        //#6  
        }
    }
    class NestedClosures {
        void run() {
            def nestedClosures = {
                def cl = { this }                               //#7
                cl()
            }
            assert nestedClosures() == this                //#8     
        }
    }
    
  • Enclosing에서 클립을 정의하고 되돌아오기getThisObject
  • 호출 클립은 Enclosing 클래스의 실례를 되돌려줍니다.
  • 보통 이런 편리한 문법을 사용합니다
  • 및 동일한 객체로 돌아갑니다
  • .
  • 클립이 내부 클래스에 정의되면
  • 클립 중this은 최고급 클래스가 아닌 내부 클래스로 돌아갑니다
  • 클로즈업이 끼워진 경우 이 곳의 c1 클로즈업은 nestedClosures 클로즈업에 정의되어 있다
  • 그럼thisc1에서 가장 가까운 외부류를 가리키는 것이지 외부 폐쇄가 아니다!!,

  • 물론 다음과 같은 방식으로 소포 종류에서 방법을 호출할 수 있습니다.
    class Person {
        String name
        int age
        String toString() { "$name is $age years old" }
    
        String dump() {
            def cl = {
                String msg = this.toString()               //#1
                println msg
                msg
            }
            cl()
        }
    }
    def p = new Person(name:'Janice', age:74)
    assert p.dump() == 'Janice is 74 years old'
    

    이 폐쇄는 this 상향 조정 toString 방법, 즉 외부 소포류 toString 방법을 사용했고, Person류의 실례에 대한 설명을 되돌려 주었다.

    3.2.2. 닫힌 Owner


    클로즈업owner의 속성은 클로즈업this과 매우 비슷하지만 약간의 미묘한 차이가 있다. 이것은 이 클로즈업의 직접 소포 대상으로 되돌아간다. 바깥쪽의 끼워 넣은 클로즈업일 수도 있고 같은 종류일 수도 있다.
    class Enclosing {
        void run() {
            def whatIsOwnerMethod = { getOwner() }    //#1           
            assert whatIsOwnerMethod() == this            //#2       
            def whatIsOwner = { owner }                     //#3     
            assert whatIsOwner() == this                  ///#4       
        }
    }
    class EnclosedInInnerClass {
        class Inner {
            Closure cl = { owner }                         //#5      
        }
        void run() {
            def inner = new Inner()
            assert inner.cl() == inner                       //#6    
        }
    }
    class NestedClosures {
        void run() {
            def nestedClosures = {
                def cl = { owner }                               //#7
                cl()
            }
            assert nestedClosures() == nestedClosures            //#8
        }
    }
    
  • 클래스에 정의된 클립, 반환Enclosing
  • 이 클립을 호출하면 getOwner의 실례
  • 를 되돌려줍니다.
  • 보통 이런 간결한 문법
  • 을 사용한다.
  • 동일한 객체 반환
  • 클로즈업이 내부 클래스에 정의된 경우
  • Enclosing최고급 클래스
  • 가 아닌 내부 클래스로 지정됨
  • 그러나 패킷을 끼워 넣은 경우 이 곳의 owner 패킷은 c1 패킷 안에 정의
  • nestedClosures은 바깥쪽에 끼워 넣은 클립을 가리키는 점owner과 다르다!!

  • 3.2.3. 닫힌delegate


    클로즈업 중thisdelegate 속성이나 호출delegate 방법으로 접근할 수 있습니다.Groovy에서 영역별 언어(domain specific languages) 구축을 돕는 강력한 도구입니다.클로즈업 중getDelegatethis는 클로즈업 중의 어법 작용역을 가리키며 owner는 사용자가 정의할 수 있는 대상이다.기본값delegatedelegate입니다.
    class Enclosing {
        void run() {
            def cl = { getDelegate() }           //#1               
            def cl2 = { delegate }                       //#2       
            assert cl() == cl2()                                //#3
            assert cl() == this                             //#4    
            def enclosed = {
                { -> delegate }.call()                          //#5
            }
            assert enclosed() == enclosed                   //#6    
        }
    }
    
  • 호출owner을 통해 폐쇄된 getDelegate() 대상
  • 또는 사용delegate 속성
  • 둘 다 같은 대상으로 되돌아오기
  • 모두 외곽의 소포류나 폐쇄
  • 특히 패킷을 끼워 넣는 경우
  • 이때delegate가 바로delegate
  • 패키지를 닫는 owner 속성은 모든 대상으로 수정할 수 있습니다.두 클래스를 만들어 이 점을 설명하자면 두 클래스는 서로 하위 클래스가 아니지만 delegate라는 속성을 정의합니다.
    class Person {
        String name
    }
    class Thing {
        String name
    }
    
    def p = new Person(name: 'Norman')
    def t = new Thing(name: 'Teapot')
    

    그리고 name 에서 delegate 속성을 추출하고 되돌려줍니다.
    def upperCasedName = { delegate.name.toUpperCase() }
    

    변경name을 통해 대상 객체가 변경되는 것을 확인할 수 있습니다.
    upperCasedName.delegate = p
    assert upperCasedName() == 'NORMAN'
    upperCasedName.delegate = t
    assert upperCasedName() == 'TEAPOT'
    

    이때.이러한 효과는 패킷을 닫는 문법 작용 영역에 정의된 delegate 대상과 차이가 없다.
    def target = p
    def upperCasedNameUsingVar = { target.name.toUpperCase() }
    assert upperCasedNameUsingVar() == 'NORMAN'
    

    그러나 본질적으로는 중요한 차이가 있다.
  • target는 국부 변수의 인용
  • 이다
  • target 접두어 없이 사용 가능
  • 3.2.4. 위임 정책


    패킷을 닫을 때 인용되지 않은 속성을 사용하면delegate 대상에게 의뢰합니다
    class Person {
        String name
    }
    def p = new Person(name:'Igor')
    def cl = { name.toUpperCase() }//#1                 
    cl.delegate = p            //#2                                 
    assert cl() == 'IGOR'    //#3  
    
  • delegate 폐쇄된 어법 작용역 내의 변수 인용이 없음
  • 변경name, 하나delegate류 실례
  • 를 가리킨다
  • 방법 호출 성공
  • 이 코드가 작동할 수 있는 이유는 Person 속성이 name 대상에게 위탁되어 실행되기 때문입니다!이것은 패키지 안에서 속성이나 방법을 해석하여 호출하는 효과적인 방법이기 때문에 현식delegate을 설정할 필요가 없다. 기본적인 패키지 위탁 정책에 따라 이런 행위는 가능하다.하나의 클로즈업은 여러 가지 선택할 수 있는 해석 전략을 정의합니다.
  • delegate.receiver가 기본 정책입니다.만약 하나의 속성/방법이 Closure.OWNER_FIRST에 존재한다면 owner에서 호출될 것이다.그렇지 않으면 owner에 의뢰됩니다.
  • delegate와 상기 전략은 정반대이다. Closure.DELEGATE_FIRST는 먼저 위탁을 받고 그 다음에 delegate에 위탁한다.
  • ownerClosure.OWNER_ONLY에서만 속성/방법을 해석하고 owner는 무시된다.
  • delegateClosure.DELEGATE_ONLY에서만 속성/방법을 해석하고 delegate는 무시된다.
  • owner는 고급 원본 컴파일링 기술이 필요하지만 사용자 정의 해석 전략을 실현하고자 하는 개발자에게 사용될 수 있다. 해석은 Closure.TO_SELFdelegate에서 하는 것이 아니라 폐쇄류 자체에서만 하는 것이다.자신의 owner자류를 실현해야만 이렇게 사용하는 것이 허용된다.

  • Closure 의 기본 정책을 코드로 설명합니다.
    class Person {
        String name
        def pretty = { "My name is $name" }        //#1     
        String toString() {
            pretty()
        }
    }
    class Thing {
        String name                              //#2       
    }
    
    def p = new Person(name: 'Sarah')
    def t = new Thing(name: 'Teapot')
    
    assert p.toString() == 'My name is Sarah'           //#3
    p.pretty.delegate = t                               //#4
    assert p.toString() == 'My name is Sarah'   //#5
    
  • 패키지 구성원 변수를 정의합니다 owner first 속성
  • 을 인용했습니다
  • name클래스와 Thing클래스는name 속성을 정의했다
  • 기본 정책을 사용하고 Person 속성은 name에서 해석됩니다
  • .
  • 변경owner지향delegate의 실례
  • 아무것도 바뀌지 않고 Thing에서 해석한다
  • 그러나 다음과 같은 기본 정책을 변경할 수 있습니다.
    p.pretty.resolveStrategy = Closure.DELEGATE_FIRST
    assert p.toString() == 'My name is Teapot'
    

    변경owner을 통해 Groovy가'은식resolveStrategy'인용을 해석하는 방식을 수정할 수 있습니다. 이런 상황에서 this는 먼저 name에서 조회하고 찾지 못하면 delegate에 조회합니다.ownername(인용delegate류의 실례)에 정의가 있기 때문에 사용된다."delegate first"와 "delegate only"(또는 "owner first"와 "owner only") 사이의 차이는 Thing(또는 delegate)에 이런 방법이나 속성이 없다면 다음과 같다.
    class Person {
        String name
        int age
        def fetchAge = { age }
    }
    class Thing {
        String name
    }
    
    def p = new Person(name:'Jessica', age:42)
    def t = new Thing(name:'Printer')
    def cl = p.fetchAge
    cl.delegate = p
    assert cl() == 42
    cl.delegate = t
    assert cl() == 42
    cl.resolveStrategy = Closure.DELEGATE_ONLY
    cl.delegate = p
    assert cl() == 42
    cl.delegate = t
    try {
        cl()
        assert false
    } catch (MissingPropertyException ex) {
        // "age" is not defined on the delegate
    }
    

    이 예에서 우리는 두 개의 클래스를 정의했는데 모두 owner 속성을 함유하고 있지만 name 클래스만 Person 속성을 성명했다.age류는 또한 하나의 폐쇄를 성명했는데 그 중에서 Person 속성을 인용했다.기본 해석 정책을 'owner first' 에서 'delegate only' 로 변경할 수 있습니다.이 클립age류는 owner류이기 때문에 우리는 Person류의 실례가 아닌지 검사할 수 있다. 만약 그렇다면 이 클립을 성공적으로 호출할 수 있지만 우리는 그것delegatePerson류의 실례로 바꾸었기 때문에 운행할 때 delegate이상을 보고할 것이다.비록 이 클립은 Person 클래스에 정의되었지만, owner는 사용되지 않았다.
    DSL(영역 특정 언어)을 개발하기 위해 이 특성을 어떻게 활용하는지에 대한 자세한 설명은 dedicated section of the manual을 참조하십시오.

    좋은 웹페이지 즐겨찾기