다음 코드에서 ( Groovy Semantics Manual 페이지 에서 가져온 ) 왜 키워드 앞에 할당을 붙 def
입니까?
def x = 0
def y = 5
while ( y-- > 0 ) {
println "" + x + " " + y
x++
}
assert x == 5
def
키워드는 제거 할 수 있으며,이 조각은 동일한 결과를 생성 할 것입니다. 키워드 의 효과 는 무엇 def
입니까?
답변
기본 스크립트의 구문 설탕입니다. “def”키워드를 생략하면 변수가 현재 스크립트의 바인딩에 들어가고 groovy는이 변수를 전역 범위 변수처럼 취급합니다.
x = 1
assert x == 1
assert this.binding.getVariable("x") == 1
대신 def 키워드를 사용하면 변수가 스크립트 바인딩에 포함되지 않습니다.
def y = 2
assert y == 2
try {
this.binding.getVariable("y")
} catch (groovy.lang.MissingPropertyException e) {
println "error caught"
}
인쇄 : “오류가 발생했습니다”
큰 프로그램에서 def 키워드를 사용하면 변수를 찾을 수있는 범위를 정의하고 캡슐화를 유지하는 데 도움이되므로 중요합니다.
스크립트에서 메소드를 정의하면 범위 내에 있지 않으므로 기본 스크립트 본문에서 “def”로 작성된 변수에 액세스 할 수 없습니다.
x = 1
def y = 2
public bar() {
assert x == 1
try {
assert y == 2
} catch (groovy.lang.MissingPropertyException e) {
println "error caught"
}
}
bar()
“오류가 발견되었습니다”
“y”변수는 함수 내에서 범위 내에 있지 않습니다. groovy가 변수에 대한 현재 스크립트의 바인딩을 검사하므로 “x”는 범위 내에 있습니다. 앞서 말했듯이, 이것은 빠르고 더러운 스크립트를 더 빨리 입력 할 수 있도록하는 구문 설탕입니다 (종종 하나의 라이너).
더 큰 스크립트에서 좋은 습관은 항상 “def”키워드를 사용하여 이상한 범위 지정 문제가 발생하거나 의도하지 않은 변수를 방해하지 않는 것입니다.
답변
Ted의 답변 은 대본에 탁월합니다. Ben의 대답 은 수업의 표준입니다.
Ben이 말했듯이 “Object”로 생각하십시오. 그러나 Object 메소드에 제한을 두지 않기 때문에 훨씬 더 시원합니다. 이것은 수입과 관련하여 깔끔한 영향을 미칩니다.
예를 들어이 스 니펫에서 FileChannel을 가져와야합니다.
// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*
import java.nio.channels.*
class Foo {
public void bar() {
FileChannel channel = new FileInputStream('Test.groovy').getChannel()
println channel.toString()
}
}
new Foo().bar()
예를 들어 여기에 모든 것이 클래스 패스에있는 한 ‘날개’할 수 있습니다.
// Groovy imports java.io.* and java.util.* automatically
// but not java.nio.*
class Foo {
public void bar() {
def channel = new FileInputStream('Test.groovy').getChannel()
println channel.toString()
}
}
new Foo().bar()
답변
이에 따라 페이지 , def
유형 이름에 대한 대체 단순히 별명으로 간주 할 수 있습니다 Object
(즉 명시를 당신이 유형에 대해 신경 쓰지 않는다).
답변
이 단일 스크립트에 관한 한 실질적인 차이는 없습니다.
그러나 키워드 “def”를 사용하여 정의 된 변수는 로컬 변수, 즉이 하나의 스크립트에 대해 로컬 변수로 취급됩니다. 앞에 “def”가없는 변수는 처음 사용할 때 소위 바인딩에 저장됩니다. 바인딩은 스크립트 사이에 사용 가능해야하는 변수 및 클로저의 일반 저장 영역으로 생각할 수 있습니다.
따라서 두 개의 스크립트가 있고 동일한 GroovyShell로 스크립트를 실행하면 두 번째 스크립트는 “def”없이 첫 번째 스크립트에서 설정된 모든 변수를 얻을 수 있습니다.
답변
“def”의 이유는 여기에 변수를 만들려고 groovy에게 알리기위한 것입니다. 우연히 변수를 만들지 않기 때문에 중요합니다.
스크립트 (Groovy 스크립트 및 groovysh를 사용하면 그렇게 할 수 있음)에서 다소 수용 가능하지만 프로덕션 코드에서는 발생할 수있는 가장 큰 악 중 하나이므로 모든 실제 그루비 코드에서 def로 변수를 정의 해야하는 이유는 무엇입니까? 수업).
다음은 왜 나쁜지에 대한 예입니다. 다음 코드를 복사하여 groovysh에 붙여 넣으면 (어설 션 실패없이) 실행됩니다.
bill = 7
bi1l = bill + 3
assert bill == 7
이런 종류의 문제는 찾아서 고치는 데 많은 시간이 걸릴 수 있습니다. 인생에서 한 번만 물렸더라도 경력 전체에서 변수를 수천 번 명시 적으로 선언하는 것보다 시간이 더 많이 걸립니다. 또한 그것이 선언되는 바로 눈에 분명해 지므로 추측 할 필요가 없습니다.
중요하지 않은 스크립트 / 콘솔 입력 (예 : 그루비 콘솔)에서는 스크립트 범위가 제한되어 있기 때문에 다소 수용 가능합니다. 나는 groovy가 스크립트에서 이것을 할 수있는 유일한 이유는 Ruby와 같은 방식으로 DSL을 지원하는 것이라고 생각합니다.
답변
사실, 나는 그것이 똑같이 행동 할 것이라고 생각 하지 않습니다 …
오른쪽에는 일반적으로 Groovy가 변수를 입력하기에 충분한 정보가 포함되어 있기 때문에 Groovy의 변수에는 여전히 TYPED 선언이 아닌 선언이 필요합니다.
def 또는 형식으로 선언하지 않은 변수를 사용하려고하면 코드가 포함 된 클래스의 멤버를 사용한다고 가정하므로 “No such property”라는 오류가 발생합니다.