JavaScript 이외의 다른 언어가 중괄호 시작 위치 (같은 줄과 다음 줄)에 차이가 있습니까?


91

오늘 저는 JavaScript patterns O'Reilly 책을 무작위로 읽는 동안 흥미로운 점을 발견했습니다 (참조 용 27 페이지).

Javascript에서는 경우에 따라 중괄호 시작 위치가 다른 경우 차이가 있습니다.

function test_function1() {
    return
    {
        name: 'rajat'
    };
}

var obj = test_function1();
alert(obj);  //Shows "undefined"

동안

function test_function2() {
    return {
        name: 'rajat'
    };
}

var obj = test_function2();
alert(obj); //Shows object

JSfiddle 데모

다른 언어에도 그러한 행동이 있습니까? 그렇다면 확실히 습관을 바꿔야 할 것입니다 .. :)

저는 주로 PHP, C, C ++, Java 및 루비에 관심이 있습니다.


1
Chrome 및 IE9에서 재현, 좋은 캐치 : P
gideon

4
공백 민감도는 작동하도록 만들 수 있습니다 .--- 파이썬 또는 라인 모드 포트란을보세요 ---- 미묘한 공백 민감도는 악마의 작업입니다. 아! 이것은 만드는 것만 큼 나쁘다!
dmckee --- 전 중재자 새끼 고양이

이것은 인상적입니다! 좋은 발견!
CheckRaise

이제 자바 스크립트가 이런 식으로 작동하는 이유를 알고 싶습니다.
CheckRaise

4
@CheckRaise : 여기서 규칙을 요약합니다 : blogs.msdn.com/b/ericlippert/archive/2004/02/02/…
Eric Lippert

답변:


53

문을 구분하기 위해 세미콜론 (대신 개행)에 의존하지 않는 모든 언어는 잠재적으로이를 허용합니다. Python을 고려하십시오 .

>>> def foo():
...   return
...   { 1: 2 }
... 
>>> def bar():
...   return { 1: 2 }
... 
>>> foo()
>>> bar()
{1: 2}

Visual Basic 에서 비슷한 케이스를 구성 할 수는 있지만 VB가 값을 배치 할 수있는 위치에 매우 제한적이기 때문에 어떻게해야할지 알 수 없습니다. 그러나 정적 분석기가 도달 할 수없는 코드에 대해 불평하지 않는 한 다음은 작동합니다.

Try
    Throw New Exception()
Catch ex As Exception
    Throw ex.GetBaseException()
End Try

' versus

Try
    Throw New Exception()
Catch ex As Exception
    Throw
    ex.GetBaseException()
End Try

언급 한 언어에서 Ruby 는 동일한 속성을 가지고 있습니다. PHP, C, C ++ 및 Java는 단순히 줄 바꿈을 공백으로 버리고 명령문을 구분하기 위해 세미콜론을 필요로하기 때문이 아닙니다.

다음은 Ruby의 Python 예제에 해당하는 코드입니다.

>> def foo
>>   return { 1 => 2 }
>> end
=> nil
>> def bar
>>   return
>>   { 1 => 2 }
>> end
=> nil
>> foo
=> {1=>2}
>> bar
=> nil

2
줄 연속 시퀀스 "_"를 사용하지 않는 한 VB 는 문이 여러 줄에 걸쳐있는 것을 허용 하지 않기 때문에 VB 예제는 그다지 중요 하지 않습니다 .
phoog

2
좋아, VB.NET이 암시 적 줄 연속을 지원하는 몇 가지 컨텍스트가 사양을 살펴 보았 기 때문에 이전 주석을 철회했습니다. 나는 그것이 꽤 명백하기 때문에 어떤 경험 VB 프로그래머는, 그러나,이 예에게 "잡았다"을 고려할 것이라고 의심 Throw하고 ex.GetBaseException()별도의 논리적 라인입니다. 좀 더 구체적으로 말하자면, Basic은 역사적으로 문장을 구분하기 위해 줄을 사용하기 때문에 프로그래머가 새로운 논리 줄에 새로운 문장을 만들었다 고 생각하지만 그렇지 않은 상황 일 가능성이 더 높습니다.
phoog

@phoog 사실, 그것은 절대적으로 문제가 아닙니다.
Konrad Rudolph

40

자바 스크립트 인터프리터는 자동으로 ;각 줄 끝에를 추가합니다 .

따라서 기본적으로 문제는 중괄호의 위치 (여기서는 대부분의 언어에서와 같이 코드 블록이 아닌 객체 리터럴을 나타냄)가 아니라 첫 번째 예제를 return ;=>로 강제하는이 작은 "기능"입니다 undefined. return ES5 사양에서의 동작을 확인할 수 있습니다 .

유사한 동작을하는 다른 언어에 대해서는 Konrad의 답변을 확인하십시오 .


5
매우 찬성 응답을 받았지만 실제로는 잘못되었습니다. 죄송합니다. 설명은 좋지만 실수를 정정하십시오.
Konrad Rudolph

JavaScript에 대한 부분은 잘못되지 않았습니다. 그처럼 동작하는 방식은 강제 undefined로 반환 되는 세미콜론 삽입 때문입니다 . 나는 afaik 접두사가 붙은 다른 언어에 대해 약간 썼 으므로 소금 한 알로 가져 가십시오 :).
Alex Ciminian 2012

5
그러나 JS가 "일부 예외를 제외하고" "각 줄의 끝에"세미콜론을 삽입한다는 것은 사실이 아닙니다. 오히려, 그것은 일반적으로 하지 않는 세미콜론을 삽입하고 단지 몇 가지 경우가있다 않습니다는 . 그것이 너무 많은 문제를 일으키는 이유입니다.
ruakh

26

거의 확실히. Google의 go 프로그래밍 언어는 매우 유사한 동작을 나타냅니다 (효과는 다르지만). 거기에 설명 된대로 :

사실 공식 언어는 C 나 Java에서와 같이 세미콜론을 사용하지만 문장의 끝처럼 보이는 모든 줄 끝에 자동으로 삽입됩니다. 직접 입력 할 필요가 없습니다.

..한조각...

이 접근 방식은 깔끔하고 세미콜론이없는 코드를 만듭니다. 한 가지 놀라운 점은 if 문과 같은 구문의 여는 중괄호를 if와 같은 줄에 두는 것이 중요하다는 것입니다. 그렇지 않으면 컴파일되지 않거나 잘못된 결과를 제공 할 수있는 상황이 있습니다. 언어는 중괄호 스타일을 어느 정도 강제합니다.

비밀리에 Rob Pike는 One True Brace Style을 요구하는 변명을 원했습니다.


10
쿨, 이것에 대해 몰랐습니다 :). 개인적으로 자동 세미콜론 삽입은 좋은 생각이 아니라고 생각합니다. 언어에 익숙하지 않은 사람들이 알아 내기 어려운 미묘한 버그를 도입 할 수 있습니다. 세미콜론 프리 코드를 작성하려면 파이썬 방식을 선호합니다.
Alex Ciminian 2012

없이 @ 알렉스 심지어 언어 어떤 세미콜론 (VB)이 속성이 있습니다. 그리고 당신이 분명히 선호하는 파이썬도 자바 스크립트와 동일하게 처리 되더라도 마찬가지입니다.
Konrad Rudolph 2012

나는 당신의 두 번째 문장이 너무 완전히 잘못되어 내가 반대표를하고 싶어한다는 점을 제외하고는 찬성 할 것입니다. 취소 된 것 같아요. ;-)
ruakh

1
@ruakh 당신은 "정확히 이것을 실행"을 의미합니까 아니면 롭 파이크에 대한 농담을 언급 했습니까? 전자의 경우 "가는 동일한 행동을 보인다"로 바꿀 수 있습니다. 후자의 경우 저 절한 유머 감각이 불쾌하면 죄송합니다.)
Dave

1
내 말은 "바둑이 정확히 이것을한다." Go의 세미콜론 삽입에 대한 원래 제안은 JavaScript의 제안과 명시 적으로 대조됩니다. "이 제안은 실제로 구문 분석 오류를 수정하기 위해 세미콜론을 추가하는 JavaScript의 선택적 세미콜론 규칙을 상기시킬 수 있습니다. Go 제안은 완전히 다릅니다." 모든 수준에서 매우 사실입니다. 작동 방식이 다르고 효과도 다르며 문제가 거의 없습니다. (이것은 모든 이동 코드의 일관된 요구 사항이기 때문에 장외 마권 발매소 집행은 성가신 동안,하는 잡았다되지 않습니다.)
ruakh

14

그 질문에 대한 답은 상당히 쉽습니다. "자동 세미콜론 삽입"이있는 언어는 해당 줄에서 문제가 될 수 있습니다. 이것의 문제

return
{
     name: 'rajat'
};

.. js 엔진이 return;문 뒤에 세미콜론을 삽입 하므로 반환 undefined합니다. 이 예는 항상 오른쪽에 중괄호를 열고 왼쪽에는 열지 않는 좋은 이유 입니다. 이미 올바르게 알아 차렸 기 때문에 같은 줄에 중괄호가 있으면 인터프리터는이를 알아 채고 세미콜론을 삽입 할 수 없습니다.


6

FWIW, JSLint 는 해당 구문으로 몇 가지 경고를보고합니다.

$ jslint -stdin
function foo(){
  return
  { x: "y" };
}
^D
(3): lint warning: unexpected end of line; it is ambiguous whether these lines are part of the same statement
  return
........^

(3): lint warning: missing semicolon
  { x: "y" };
..^

(3): lint warning: unreachable code
  { x: "y" };
..^

(3): lint warning: meaningless block; curly braces have no impact
  { x: "y" };
..^

(3): lint warning: use of label
  { x: "y" };
.....^

(3): lint warning: missing semicolon
  { x: "y" };
...........^

(3): lint warning: empty statement or extra semicolon
  { x: "y" };
............^


0 error(s), 7 warning(s)

1

내가 이것을 발견 한 첫 번째 언어는 awk (구문 "이상"의 몫도 있습니다. 선택적인 세미콜론, 공백 만 사용하는 문자열 연결 등 ...) D 구문을 느슨하게 기반으로 한 DTrace 디자이너가 생각합니다. awk에, 이러한 기능을 복사하지 않을 충분한 감각이 있었지만 머리 꼭대기에서 기억할 수 없습니다. 간단한 예 (Mac에서 DTD의 ENTITY 태그 수 계산) :

$ cat printEntities.awk 
# This prints all lines where the string ENTITY occurs
/ENTITY/ {
  print $0
}
$ awk -f printEntities.awk < /usr/share/texinfo/texinfo.dtd | wc -l
     119

대신이 작은 스크립트가 자체 줄에 중괄호로 작성 되었다면 다음과 같은 결과가 발생합니다.

$ cat printAll.awk 
# Because of the brace placement, the print statement will be executed
# for all lines in the input file
# Lines containing the string ENTITY will be printed twice,
# because print is the default action, if no other action is specified
/ENTITY/
{ 
   print $0 
}
$ awk -f printAll.awk < /usr/share/texinfo/texinfo.dtd | wc -l
     603
$ /bin/cat < /usr/share/texinfo/texinfo.dtd | wc -l
     484
$ 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.