예를 들어,이 단일 라이너를 선호합니까
int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
또는 여러 반환 문이 포함 된 if / else 솔루션입니까?
?:
적절한 시기는 언제 입니까? 초보자에게 가르쳐야하거나 숨겨야합니까?
예를 들어,이 단일 라이너를 선호합니까
int median(int a, int b, int c) {
return (a<b) ? (b<c) ? b : (a<c) ? c : a : (a<c) ? a : (b<c) ? c : b;
}
또는 여러 반환 문이 포함 된 if / else 솔루션입니까?
?:
적절한 시기는 언제 입니까? 초보자에게 가르쳐야하거나 숨겨야합니까?
답변:
삼항 연산자는 사악합니까?
아니요 축복입니다.
언제? : 적절한가?
그것이 너무 간단한 일이라면 많은 줄을 낭비하고 싶지 않습니다.
언제 그렇지 않습니까?
코드의 가독성과 명료성이 떨어지고 예를 들어 많은 체인 연산자가 예를 들어 불충분 한주의를 기울이면 실수가 발생할 가능성이 높아집니다.
리트머스 테스트는 장기적으로 코드를 쉽게 읽고 유지 관리 할 수 있는지 의심하기 시작합니다. 그런 다음하지 마십시오.
myVar = someExpression ? false : true;
(someExpression ? var1 : var2)++
:-)
나는 중첩되지 않은 삼항 연산자 (즉, 한 번만 사용되는 명령문)는 괜찮다고 생각하지만 둘 이상 중첩하면 읽기가 다소 어려워집니다.
아무도 지적하지 않은 한 가지 차이점은 if-else는 값을 반환 할 수 없지만 삼항 연산자는 반환 할 수 없다는 것입니다.
F #에서 왔을 때, 때때로 삼항 연산자를 사용하여 패턴 일치를 모방하고 싶습니다.
match val with
| A -> 1
| B -> 3
| _ -> 0
vs
return val == A ? 1 :
val == B ? 3 :
0;
var res = function() {switch(input) {case 1: return "1"; case 2: return "2"; ...}}()
스위치를 표현식으로 에뮬레이트하는 것입니다.
expression
및 statement
하지만 난 항상 걱정 나는 라운드 그들에게 길을 잘못 얻을 :) 자신의 바보 만들거야
const
나중에 변경할 수없는 변수 를 초기화하는 데 C 및 C ++에서 유용합니다 .
유효한 사용 예 (IMHO) :
printf("Success in %d %s\n", nr_of_tries, (nr_of_tries == 1 ? "try" : "tries"));
결과적으로 2 개의 고유 한 인쇄 명령문을 사용하는 것보다 더 읽기 쉬운 코드가 생성됩니다. 중첩 된 예제는 다음에 의존합니다. (이해할 수 있습니까? 예 : 아니오)
절대로 악하지 않습니다. 사실, 그것은 순수 하고 그렇지 않으면 그렇지 않습니다.
Haskell, F #, ML 등과 같은 기능적 언어에서는 사악한 것으로 간주되는 if-then-else 문입니다.
그 이유는 명령형 if-then-else 문과 같은 "조치"는 변수 선언과 정의를 분리해야하고 상태 를 함수에 도입 하기 때문입니다.
예를 들어 다음 코드에서
const var x = n % 3 == 1
? Parity.Even
: Parity.Odd;
vs.
Parity x;
if (n % 3 == 1)
x = Parity.Even;
else
x = Parity.Odd;
첫 번째는 더 짧은 것 외에 두 가지 장점이 있습니다.
x
일정하며 버그를 도입 할 가능성이 훨씬 적으며, 두 번째로는 결코 할 수없는 방식으로 최적화 될 수 있습니다.x
형식 이 필요한 것을 쉽게 유추 할 수 있습니다 Parity
.혼란스럽게도 기능적 언어에서 삼항 연산자는 종종 if-then-else라고합니다. 하스켈에서는이라고 말할 수 있습니다 x = if n mod 3 == 1 then Odd else Even
.
그 특별한 표현은 내 눈을 아프게합니다. 유지 보수가 불가능하기 때문에 팀에서 사용한 모든 개발자를 래시합니다.
삼항 연산자는 잘 사용될 때 악하지 않습니다. 심지어 한 줄일 필요도 없습니다. 형식이 긴 긴 것은 매우 명확하고 이해하기 쉽습니다.
return
( 'a' == $s ) ? 1
: ( 'b' == $s ) ? 2
: ( 'c' == $s ) ? 3
: 4;
나는 동등한 if / then / else 체인보다 그것을 좋아합니다.
if ( 'a' == $s ) {
$retval = 1;
}
elsif ( 'b' == $s ) {
$retval = 2;
}
elsif ( 'c' == $s ) {
$retval = 3;
}
else {
$retval = 4;
}
return $retval;
나는 그것들을 다음과 같이 다시 포맷 할 것이다 :
if ( 'a' == $s ) { $retval = 1; }
elsif ( 'b' == $s ) { $retval = 2; }
elsif ( 'c' == $s ) { $retval = 3; }
else { $retval = 4; }
return $retval;
조건과 과제가 쉬운 정렬을 허용하는 경우. 여전히 나는 삼원 버전이 더 짧고 조건과 과제에 대해 소음이 적기 때문에 선호합니다.
ReSharper에서 VS.NET에서 때때로 교체 제안 if...else
와 ?:
운영자.
ReSharper는 조건 / 차단이 특정 복잡도 수준 미만인 경우에만 제안하는 것으로 보이며 그렇지 않은 경우 계속 표시됩니다 if...else
.
이것은 if / else 조합처럼 멋지게 재구성 될 수 있습니다.
int median(int a, int b, int c)
{
return
(a<b)
?
(b<c)
? b
:
(a<c)
? c
: a
:
(a<c)
? a
:
(b<c)
? c
: b;
}
그러나 문제는 실제로 일어날 일을 나타낼 수있는 들여 쓰기 권한이 있는지 확실하지 않다는 것입니다. :-)
if-else
구조 보다 훨씬 낫다고 생각합니다 . 열쇠는 형식입니다.
삼항 연산자는 악이 아니라 신의 선물입니다.
중첩 식에서 결정을 내릴 때 가장 유용 합니다. 전형적인 예는 함수 호출입니다.
printf("I see %d evil construct%s in this program\n", n, n == 1 ? "" : "s");
특정 예에서 삼항은에 대한 최상위 표현식이므로 거의 무의미합니다 return
. return
키워드 이외의 다른 항목을 복제하지 않고도 조건부를 명령문 레벨로 해제 할 수 있습니다 .
NB 어떤 것도 중간 값을 쉽게 읽을 수있는 특정 알고리즘을 만들 수 없습니다.
printf("I see %d evil construct%s in this program\n", n, "s" unless (n == 1) "s");
"사악한"주장을 제외하고는 필자의 경험에 따르면 프로그래머의 삼항 연산자 사용과 전체 코드베이스를 읽고 따르고 유지하기가 어려울 가능성 (문서화되지 않은 경우) 사이에 높은 상관 관계가 있음을 발견했습니다. 프로그래머가 자신의 코드를 이해할 수있는 사람보다 1-2 자 정도의 문자를 저장하는 데 더 관심이있는 경우, 3 진법을 이해하는 사소한 혼란은 대개 빙산의 일각입니다.
삼항 연산자는 s ** t가 파리를 끌어 당기는 것처럼 마법의 숫자를 끌어들입니다.
특정 문제를 해결하기 위해 오픈 소스 라이브러리를 찾고 있었는데 해당 라이브러리의 후보에서 원래 포스터의 삼항 연산자와 같은 코드를 보았을 때 경고 벨이 내 머리에서 떨어지기 시작하고 계속 진행하기 시작했습니다. 빌릴 다른 프로젝트에.
다음 은 악한 경우의 예입니다 .
oldValue = newValue >= 0 ? newValue : oldValue;
혼란스럽고 낭비입니다. 컴파일러 는 두 번째 표현식 (oldValue = oldValue)을 최적화 할 수 있지만 코더는 왜 처음에 이것을 했습니까?
또 다른 doozy :
thingie = otherThingie != null ? otherThingie : null;
어떤 사람들은 코더가되어서는 안됩니다 ...
Greg는 동등한 if 문이 '잡음'이라고 말합니다. 당신이 그것을 시끄럽게 쓰는 경우입니다. 그러나 다음과 같이 쓸 수 있다면 동일합니다.
if ('a' == $s) return 1;
if ('b' == $s) return 2;
if ('c' == $s) return 3;
return 4;
삼항보다 더 시끄럽지 않습니다. 삼항 지름길인지 궁금합니다. 모든 표현이 평가됩니까?
if (x != 0) x = 0;
...
악? 봐, 그들은 단지 다르다.
if
진술입니다. (test ? a : b)
식입니다. 그들은 같은 것이 아닙니다.
값을 표현하기위한 표현이 존재합니다. 조치를 수행하기위한 명령문이 있습니다. 문 안에식이 나타날 수 있지만 그 반대는 아닙니다. 따라서 요약의 용어 또는 메서드의 인수 등과 같은 다른 식 내에서 삼항 식을 사용할 수 있습니다. 당신은하지 않습니다 에있다 , 그러나 당신은 당신이 원하는 수있는 경우 . 그것에 아무런 문제가 없습니다. 어떤 사람들은 그것이 악하다고 말하지만 그것은 그들의 의견입니다.
삼항 표현식의 한 가지 가치는 대 / 소문자를 모두 처리 할 수 있다는 것입니다. if
진술하지 않습니다.
가독성이 걱정되면 쉽게 읽을 수 있도록 형식을 지정할 수 있습니다.
어떻게 든 "악한"프로그래밍 어휘에 들어갔다. 누가 먼저 떨어 뜨 렸는지 알고 싶습니다. (실제로, 나는 용의자가 있습니다-그는 MIT에 있습니다.) 오히려 우리는 사람들의 취향과 이름을 부르는 것만이 아니라이 분야에서 가치 판단의 객관적인 이유를 갖고 싶습니다.
장소가 있습니다. 나는 개발자의 기술 수준이 끔찍한 마법사에서 마법사에 이르기까지 많은 회사에서 근무했습니다. 코드를 유지 관리하고 영원히 거기에 있지 않기 때문에 코드가 속하는 것처럼 보이도록 항목을 작성하려고합니다 (내 이니셜로 주석을 보지 않고는 거의 할 수 없습니다. 내가 변경 한 위치를 확인하기 위해 작업 한 코드를 살펴보십시오.
삼항 연산자가 열광적이고 멋지게 보이지만 내 경험에 따르면 코드 줄을 유지 관리하기가 거의 불가능합니다. 현재 고용주에게는 거의 20 년 동안 배송 된 제품이 있습니다. 나는 그 예제를 어디에도 사용하지 않을 것이다.
말할 수 있습니까? 나는 삼항 작업이 특정 응용 프로그램을 찾을 관리 할 수 악을 :
자비를 베풀어주세요. 제 평판은 이미 불쌍합니다.
가장 큰 승리 : 단일 행동 목표가 있음을 보여줍니다.
if ( $is_whatever )
$foo = 'A';
else
$foo = 'B';
따라갈 수있는 두 가지 코드 경로가 있으며 독자는 두 변수를 설정하기 위해주의해서 읽어야합니다. 이 경우에는 하나의 변수 일 뿐이지 만 독자는이를 이해하기 위해 더 읽어야합니다. 결국, 이것은 다음과 같을 수 있습니다.
if ( $is_whatever )
$foo = 'A';
else
$bar = 'B';
삼항 연산자를 사용하면 하나의 변수 만 설정됩니다.
$foo = $is_whatever ? 'A' : 'B';
가장 낮은 수준에서는 가장 기본적으로 DRY (Do n't Repeat Yourself) 원칙입니다. $foo
한 번만 지정할 수 있으면 지정하십시오 .
연산자 자체는 악의가 없지만 C (및 C ++)에서 사용되는 구문은 너무 간결합니다. IMO, Algol 60이 더 잘 했으므로 다음과 같이하십시오.
A = x == y ? B : C;
다음과 같이 보일 것입니다 (그러나 일반적으로 C와 같은 구문을 고수하십시오).
A = if (x==y) B else C;
그럼에도 불구하고 과도한 중첩은 가독성에 문제를 일으킬 수 있지만 적어도 A) 프로그래밍을 한 사람은 누구나 간단한 것으로 파악할 수 있으며 B) 이해하는 사람들은 상당히 깊은 중첩을 쉽게 처리 할 수 있습니다. OTOH, 나는 또한 LISP에서 (예를 들어) a cond
는 문장의 집합이 아니라 삼항 문장과 거의 비슷하지만 단일 표현식은 값을 산출합니다 (다시 말하면, 대부분의 LISP는 그와 같습니다.) .)
A = (x==y) ? B : C
?는 언제 적절한가?
초보자에게 가르쳐야하거나 숨겨야합니까?
중요하지 않지만 "초보자"가 배우기에는 너무 복잡하지 않으므로 의도적으로 숨겨서는 안됩니다.
귀하의 예에서 :
def median(a, b, c):
if a < b < c: return b
if a < c < b: return c
if b < a < c: return a
if b < c < a: return c
if c < a < b: return a
if c < b < a: return b
읽기 쉽고 명확합니다. <<사이의 변수는 반환 값입니다.
동일하지만 더 적은 코드 줄. 여전히 간단하다고 생각합니다.
def median(a, b, c):
if b<a<c or c<a<b: return a
if a<b<c or c<b<a: return b
if a<c<b or b<c<a: return c
const에도 필요합니다.
const int nLegs = isChicken ? 2: 4 ;
const
특정 언어에서는 그렇게 생각 합니다. C #에서는 const
항상 컴파일 타임 알려진 값이어야합니다. 그 말은 const int nLegs = isChicken ? 2: 4 ;
늘 일을하지만 const int nLegs = true ? 2: 4 ;
것