C / C ++ (및 그 계열의 여러 언어)에서 조건에 따라 변수를 선언하고 초기화하는 일반적인 관용구는 삼항 조건 연산자를 사용합니다.
int index = val > 0 ? val : -val
Go에는 조건부 연산자가 없습니다. 위와 동일한 코드를 구현하는 가장 관용적 인 방법은 무엇입니까? 나는 다음 해결책에 왔지만 꽤 장황한 것처럼 보인다.
var index int
if val > 0 {
index = val
} else {
index = -val
}
더 좋은 것이 있습니까?
답변
지적했듯이 (그리고 놀랍지 않게도) 사용하는 if+else
것은 실제로 Go에서 조건부를 수행 하는 관용적 방법 입니다.
그러나 완전한 var+if+else
코드 블록 외에도이 철자가 자주 사용됩니다.
index := val
if val <= 0 {
index = -val
}
및와 같이 반복 가능한 코드 블록이 있으면이 int value = a <= b ? a : b
를 보유하는 함수를 만들 수 있습니다.
func min(a, b int) int {
if a <= b {
return a
}
return b
}
...
value := min(a, b)
컴파일러는 이러한 간단한 함수를 인라인하므로 빠르고 명확하며 짧습니다.
답변
No Go에는 if / else 구문 을 사용 하는 관용적 인 삼항 연산자가 없습니다 .
Go에? : 연산자가없는 이유는 무엇입니까?
Go에는 3 진 테스트 작업이 없습니다. 다음을 사용하여 동일한 결과를 얻을 수 있습니다.
if expr { n = trueVal } else { n = falseVal }
?:
Go에 빠진 이유 는 언어 디자이너가 조작이 너무 자주 사용되어 복잡한 표현을 만들지 못했기 때문입니다.if-else
형태는 이상하지만, 의심 할 여지없이 명확하다. 언어에는 조건부 제어 흐름 구성이 하나만 필요합니다.— 자주 묻는 질문 (FAQ)-Go 프로그래밍 언어
답변
다음과 같은 삼항식이 있다고 가정합니다 (C).
int a = test ? 1 : 2;
Go의 관용적 접근 방식은 단순히 if
블록을 사용하는 것입니다 .
var a int
if test {
a = 1
} else {
a = 2
}
그러나 이는 요구 사항에 맞지 않을 수 있습니다. 필자의 경우 코드 생성 템플릿에 인라인식이 필요했습니다.
즉시 평가 된 익명 함수를 사용했습니다.
a := func() int { if test { return 1 } else { return 2 } }()
이렇게하면 두 가지 모두 평가되지 않습니다.
답변
지도 삼항은 괄호없이 읽기 쉽습니다.
c := map[bool]int{true: 1, false: 0} [5 > 4]
답변
func Ternary(statement bool, a, b interface{}) interface{} {
if statement {
return a
}
return b
}
func Abs(n int) int {
return Ternary(n >= 0, n, -n).(int)
}
그렇지 않으면 캐스팅보다 성능이 뛰어나지 않지만 작동합니다. 참고 사항 :
벤치 마크 : AbsTernary-8 100000000 18.8 ns / op
BenchmarkAbsIfElse-8 2000000000 0.27 ns / op
답변
경우 모든 당신의 가지 부작용을 만들 거나있는 많은 계산 다음은을 것이다 의미 보존 리팩토링 :
index := func() int {
if val > 0 {
return printPositiveAndReturn(val)
} else {
return slowlyReturn(-val) // or slowlyNegate(val)
}
}(); # exactly one branch will be evaluated
일반적으로 오버 헤드 (인라인 된)가 없으며 가장 중요 하게는 한 번만 사용되는 도우미 함수로 네임 스페이스를 어지럽히 지 않고 (가독성 및 유지 관리를 방해합니다). 라이브 예
구스타보의 접근 방식 을 순진하게 적용한다면 같습니다.
index := printPositiveAndReturn(val);
if val <= 0 {
index = slowlyReturn(-val); // or slowlyNegate(val)
}
당신은 다른 행동을 가진 프로그램을 얻게 될 것입니다 ; val <= 0
프로그램이 양수가 아닌 값을 인쇄하는 경우에는 그렇지 않습니다! (분명히 분기를 반전하면 불필요하게 느린 함수를 호출하여 오버 헤드가 발생합니다.)
답변
서문 : 주장하지 않고if else
갈 길이 , 우리는 여전히 언어 기반 구조를 가지고 놀고 즐거움을 찾을 수 있습니다.
다음 If
구성은 github.com/icza/gox
라이브러리에서 다른 많은 방법으로 사용할 수 있으며 builtinx.If
유형입니다.
Go 는와 같은 기본 유형을 포함 하여 모든 사용자 정의 유형 에 메소드를 첨부 할 수 있습니다 bool
. 기본 유형bool
으로 사용자 정의 유형을 작성한 다음 조건에 대한 간단한 유형 변환 으로 메소드에 액세스 할 수 있습니다. 피연산자를 받고 선택하는 메소드입니다.
이 같은:
type If bool
func (c If) Int(a, b int) int {
if c {
return a
}
return b
}
어떻게 사용할 수 있습니까?
i := If(condition).Int(val1, val2) // Short variable declaration, i is of type int
|-----------| \
type conversion \---method call
예를 들어 삼항 max()
:
i := If(a > b).Int(a, b)
삼항 abs()
:
i := If(a >= 0).Int(a, -a)
멋있고, 단순하고 우아하며 효율적입니다 ( 인라인 에도 적합 함) ).
“실제”삼항 연산자와 비교할 때 한 가지 단점 : 항상 모든 피연산자를 평가합니다.
지연되고 필요한 경우에만 평가를 수행하려면 필요한 경우 / 필요할 때만 호출되는 함수 ( 선언 된 함수 또는 메소드 또는 함수 리터럴 ) 를 사용하는 것이 유일한 옵션입니다 .
func (c If) Fint(fa, fb func() int) int {
if c {
return fa()
}
return fb()
}
그것을 사용 :하자의 우리가 계산에 이러한 기능이 가정 a
및 b
:
func calca() int { return 3 }
func calcb() int { return 4 }
그때:
i := If(someCondition).Fint(calca, calcb)
예를 들어, 현재 연도> 2020 인 조건 :
i := If(time.Now().Year() > 2020).Fint(calca, calcb)
함수 리터럴을 사용하려는 경우 :
i := If(time.Now().Year() > 2020).Fint(
func() int { return 3 },
func() int { return 4 },
)
마지막 참고 사항 : 서명이 다른 기능이있는 경우 여기서 사용할 수 없습니다. 이 경우 서명이 일치하는 함수 리터럴을 사용하여 여전히 적용 할 수 있습니다.
예를 들어 calca()
및 calcb()
매개 변수가있는 경우 (반환 값 외에) :
func calca2(x int) int { return 3 }
func calcb2(x int) int { return 4 }
이것은 당신이 그들을 사용할 수있는 방법입니다 :
i := If(time.Now().Year() > 2020).Fint(
func() int { return calca2(0) },
func() int { return calcb2(0) },
)
Go Playground 에서이 예제를 사용해보십시오 .
![](http://daplus.net/wp-content/uploads/2023/04/coupang_part-e1630022808943-2.png)