거의 모든 현대 프로그래밍 언어 (Go, Rust, Kotlin, Swift, Scala, Nim, Python last version)에서 유형이 항상 변수 선언에서 변수 이름 뒤에 오는 이유는 무엇입니까?
왜 x: int = 42
그렇지 int x = 42
않습니까?
후자는 전자보다 더 읽기 쉽지 않습니까?
트렌드 일까, 아니면이 솔루션 뒤에 정말 의미있는 이유가 있습니까?
답변
언급 한 모든 언어는 형식 유추를 지원 합니다. 즉 , 유형이 쉽게 결정되는 유형의 초기화 표현식을 제공 할 때 자체적으로 입력 할 수 있기 때문에 유형이 해당 언어로 선언의 선택적 부분입니다 .
표현식의 선택적 부분을 오른쪽으로 더 멀리 배치하면 구문 분석 모호성이 줄어들고 해당 부분을 사용하는 표현식과 사용하지 않는 표현식 사이의 일관성이 향상되기 때문에 중요합니다. var
선택 사항에 도달하기 전에 키워드와 변수 이름이 모두 필수 인 것을 알면 선언을 구문 분석하는 것이 더 간단합니다 . 이론적으로, 컴퓨터가보다 쉽게 분석 할 수 있도록 그 모든 것들을 해야 너무 인간에 대한 전반적인 가독성을 향상,하지만 더 많은 논쟁의 여지가있다.
당신과 같은 C ++와 같은 “비 현대적인”언어가 모든 옵션 유형 수정, 고려할 때이 인수는 특히 강력한 얻는다 *
포인터를 들어 &
, 참조를 들어 const
, volatile
등등. 여러 선언에 쉼표를 넣으면 포인터를 int* a, b;
만들지 않는 것과 같은 이상한 모호한 점이 생깁니다 b
.
심지어 C ++는 지금의 형태로 선언 “오른쪽 유형”을 지원 auto x = int{ 4 };
하고, 그것은 몇 가지 장점을 가지고있다 .
답변
거의 모든 현대 프로그래밍 언어 (Go, Rust, Kotlin, Swift, Scala, Nim, 심지어 Python 마지막 버전)에서 유형이 항상 변수 선언 이후에 오는 이유는 무엇입니까?
전제는 두 가지 측면에서 결함이 있습니다.
- 식별자 앞에 유형이있는 새로운 프로그래밍 언어가 있습니다 . 예를 들어 C♯, D 또는 실론입니다.
- 식별자 뒤에 유형이있는 것은 새로운 현상이 아니며, 적어도 Pascal (1968-1969 년에 발표 된 1970 년에 발표)로 돌아가지만 실제로는 수학 유형 이론에 사용되어 ~ 1902에서 시작합니다. ML (1973), CLU (1974), Hope (1970s), Modula-2 (1977–1985), Ada (1980), Miranda (1985), Caml (1985), Eiffel (1985), Oberon에서도 사용되었습니다. (1986), Modula-3 (1986-1988) 및 Haskell (1989).
Pascal, ML, CLU, Modula-2 및 Miranda는 모두 매우 영향력있는 언어 였으므로 이러한 유형의 선언이 인기를 유지 한 것은 놀라운 일이 아닙니다.
왜
x: int = 42
그렇지int x = 42
않습니까? 후자는 전자보다 더 읽기 쉽지 않습니까?
가독성은 친숙한 문제입니다. 개인적으로 중국인은 읽을 수 없지만 중국인은 읽을 수없는 것으로 보입니다. 학교에서 파스칼을 배우고, 에펠, F♯, 하스켈, 스칼라를 습격하고 TypeScript, Fortress, Go, Rust, Kotlin, Idris, Frege, Agda, ML, Ocaml 등을 살펴보면… .
그것은 단지 추세일까요, 아니면 그러한 해결책 뒤에 정말로 의미있는 이유가 있습니까?
그것이 추세라면, 그것은 꽤 영속적입니다. 제가 언급했듯이, 수학에서 백 년 전으로 거슬러 올라갑니다.
식별자 다음에 유형을 갖는 주요 이점 중 하나는 유추하려는 경우 유형을 쉽게 제외 할 수 있다는 것입니다. 선언이 다음과 같은 경우 :
val i: Int = 10
그런 다음 유형을 생략하고 다음과 같이 추론하는 것이 쉽지 않습니다.
val i = 10
반면에 타입이 식별자 앞에 오는 경우 :
Int i = 10
그런 다음 구문 분석기가 표현식을 선언과 구별하기가 어려워집니다.
i = 10
언어 디자이너가 일반적으로 생각하는 해결책은 유형 대신 작성해야하는 “유형을 작성하고 싶지 않습니다”키워드를 소개하는 것입니다.
var i = 10; // C♯
auto i = 10; // C++
그러나 이것은 실제로 의미가 없습니다. 기본적으로 유형을 쓰지 않는다는 유형을 명시 적으로 작성해야합니다. 응? 그냥 빼는 것이 훨씬 쉽고 합리적이지만 문법이 훨씬 복잡해집니다.
(그리고 C의 함수 포인터 타입 에 대해서도 이야기하지 않겠 습니다.)
앞서 언급 한 여러 언어의 설계자들이이 주제에 무게를 두었습니다.
-
Go FAQ (참조 : Go ‘s Declaration Syntax ) :
왜 선언이 거꾸로됩니까?
C에 익숙하다면 그것들은 거꾸로되어 있습니다. C에서, 변수는 타입을 나타내는 표현식처럼 선언됩니다. 좋은 생각이지만, 타입과 표현식 문법은 잘 섞이지 않습니다. 결과는 혼란 스러울 수 있습니다. 함수 포인터를 고려하십시오. Go는 대부분 식과 형식 구문을 분리하며 사물을 단순화합니다 (
*
포인터에 접두사 를 사용 하는 것은 예외입니다). C에서 선언int* a, b;
a
포인터로 선언 하지만 그렇지 않습니다b
. 이동 중var a, b *int
둘 다 포인터로 선언합니다. 이것은 더 명확하고 규칙적입니다. 또한,
:=
짧은 고지서 전체 변수 선언과 같은 순서를 제시한다고 주장:=
때문에var a uint64 = 1
같은 효과가 있습니다
a := uint64(1)
또한 표현 문법이 아닌 유형에 대해 고유 한 문법을 사용하여 구문 분석을 단순화 할 수 있습니다. 같은 키워드
func
와는chan
명확하게하기. -
코 틀린 FAQ :
왜 타입 선언이 오른쪽에 있습니까?
코드를 더 읽기 쉽게 만든다고 생각합니다. 게다가, 그것은 좋은 구문 기능을 가능하게합니다. 예를 들어, 타입 주석을 남기기 쉽습니다. 스칼라는 또한 이것이 문제가되지 않는다는 것을 잘 증명했다.
-
Java와의 주요 편차는 유형 주석의 구문과 관련이 있습니다. Java에서 ”
variable: Type
“대신 ”Type variable
“입니다. 스칼라의 접미사 유형 구문은 Pascal, Modula-2 또는 Eiffel과 유사합니다. 이 편차의 주된 이유는 유형 유추와 관련이 있으며, 종종 변수의 유형 또는 메소드의 반환 유형을 생략 할 수 있습니다. ”variable: Type
“구문을 사용하면 이 작업이 쉬워집니다. 콜론과 유형은 그대로 두십시오. 그러나 C 스타일 ”Type variable
“구문에서는 단순히 유형을 생략 할 수 없습니다. 더 이상 정의를 시작하기위한 마커가 없습니다. 누락 된 유형 (일부 유형 유추를 수행하는 C♯ 3.0,var
이 목적으로 사용)에 대한 자리 표시자가 되려면 대체 키워드가 필요합니다 . 이러한 대안 키워드는 스칼라의 접근 방식보다 임시적이고 덜 규칙적입니다.
참고 : Ceylon의 설계자들은 접두사 유형 구문을 사용하는 이유를 문서화했습니다 .
접미사 유형 주석 대신 접두사
왜 파스칼과 ML 대신 선언 이름 뒤에 주석을 달 때 C와 Java를 따라 유형 주석을 먼저 넣습니까?
우리는 이것을 생각하기 때문에 :
shared Float e = .... shared Float log(Float b, Float x) { ... }
이것보다 훨씬 쉽게 읽을 수 있습니다.
shared value e: Float = .... shared function log(b: Float, x: Float): Float { ... }
그리고 우리는 다른 사람이 어떻게 다르게 생각할 수 있는지 이해하지 못합니다!
개인적으로, 나는 그들의 “인수”가 다른 사람들보다 훨씬 더 설득력이 있다고 생각합니다.
답변
파스칼도 그렇게하고 새로운 언어는 아닙니다. 그것은 처음부터 고안된 학문 언어였습니다.
변수 이름으로 시작하는 것이 의미 적으로 더 명확하다고 말하고 싶습니다. 유형은 기술적 인 세부 사항입니다. 실제 모델과 같은 클래스를 읽고 싶다면 엔티티의 이름을 먼저 지정하고 기술적 구현을 마지막에 배치하는 것이 좋습니다.
C #과 Java는 C에서 유래하므로 “선행 기술”을 존중해야하므로 숙련 된 프로그래머를 혼동하지 마십시오.
답변
왜
x: int = 42
그렇지int x = 42
않습니까? 후자는 전자보다 더 읽기 쉽지 않습니까?
이러한 간단한 예에서는 큰 차이가 없지만 조금 더 복잡하게 만들어 봅시다. int* a, b;
이것은 C에서 실제로 유효한 선언이지만 직관적으로 보이는 것처럼 행동하지 않습니다. 우리는 type의 두 변수를 선언하는 것처럼 int*
보이지만 실제로는 one int*
과 one을 선언 하고 int
있습니다.
언어가 선언에서 변수 이름 뒤에 유형 을 넣으면 그 문제를 해결할 수 없습니다.