타입 시스템 : 명목 vs. 구조적, 명시 적 vs. 암시 적


24

공칭 및 구조 유형 시스템의 차이점에 대해 약간 혼란 스럽습니다. 누군가가 어떻게 다른지 설명해 주시겠습니까?

내가 이해 한 것에서 :

  • 명목 : 유형 호환성은 유형 이름을 기반으로합니다.
  • 구조 : 유형 호환성은 유형 구조를 기반으로합니다 (예 : 2 개의 변수가 이름은 다르지만 동일한 구조를 가진 구조체 유형 인 경우 C에서 유형은 호환 가능).

이제 명시 적 및 암시 적 정보 : 정적 및 동적 입력과 다른 이유는 무엇입니까? 정적 타이핑에서는 유형이 명시 적이지만 동적 타이핑에서는 유형이 암시 적입니다. 내가 맞아?

답변:


29

동적으로 유형이 지정된 시스템에서 값은 런타임시 유형을 갖지만 변수와 함수는 유형이 없습니다. 정적으로 유형이 지정된 시스템에서 변수와 함수에는 컴파일 타임에 알려진 유형과 확인 된 유형이 있습니다. 예를 들어 파이썬 x에서는 무엇이든 될 수 있습니다 . 런타임에 1숫자이면 숫자이고 "foo"문자열 이면 문자열입니다. x런타임에 어떤 유형인지 알 수 있으며 프로그램을 실행할 때마다 유형 이 다를 수 있습니다. Java와 같은 언어에서는 숫자를 사용해야하는 int x경우 x를 작성 하고 컴파일 타임에는 x항상이어야하는 것을 알 수 있습니다 int.

"명시 적"및 "내재적"유형은 모두 정적 유형 시스템을 나타냅니다. 정적 시스템의 특징은 컴파일 타임에 형식이 알려져 있지만 반드시 형식을 작성해야하는 것은 아니라는 것입니다. Java에서는 유형이 명시 적이므로이를 작성해야합니다. 따라서 Java에서 메소드는 다음과 같습니다.

public int foo(String bar, Object baz) { ... }

유형은 컴파일 타임 (정적) 기록 (명시 적)으로 알려져 있습니다. 그러나 형식을 쓰도록 강요 하지 않는 언어도 있습니다 . 그것들은 그것의 몸에서 함수의 타입과 그것이 어떻게 사용되는지 추론 할 수 있습니다 . 예를 들어 다음과 같이 작성할 수있는 OCaml이 있습니다.

let foo x = x + 1

를 사용했기 때문에 +OCaml은 그 자체 xint전부 인지 알아낼 수 있습니다 . 그래서의 종류는 foo( foo : int -> int) 입니다 단지 자바 예제와 같이, 컴파일시에 알려져 있습니다. 완전히 정적입니다. 그러나 컴파일러는 유형 자체가 무엇인지 파악할 수 있으므로 직접 작성할 필요는 없습니다. 암시 적입니다.

간단히 말해서 유형 시스템이 명시 적이든 암시 적이든 정적 시스템 의 속성입니다 . 타입 시스템이 동적인지 정적인지와는 완전히 다른 질문입니다.

종종 때로는 명시 적이거나 암시적인 유형 시스템이 있습니다.

예를 들어 C #에서는 var키워드를 사용하여 유형을 유추 할 수 있다고 생각 합니다. 그래서 쓰는 대신 int x = 10, 당신은 쓸 수 var x = 10및 그 밖의 컴파일러 수치는 x을 수있다 int. C ++는와 비슷한 작업을 수행 auto합니다. 이러한 시스템은 일반적으로 명시 적이지만 약간의 추론이 있습니다.

반대로, 일반적으로 암시 적이지만 때로는 유형 서명을 작성해야하는 시스템이 있습니다. 하스켈이 좋은 예입니다. 대부분의 경우 Haskell은 유형을 유추 할 수 있습니다. 그러나 때때로 show . readHaskell이 자체적으로 유형을 파악할 수없는 모호한 코드를 작성할 수 있습니다. 이 경우 show또는 의 유형을 명시 적으로 지정해야합니다 read. 또한 순위 시스템의 다형성과 같은 형식 시스템의 일부 고급 기능으로 인해 추론을 결정할 수 없습니다. 즉, 중지되지는 않습니다. 즉,이 기능을 사용하는 코드에는 종종 명시적인 유형 서명이 필요합니다.


2
실제로 명시 적 동적 타이핑 이라고 할 수있는 언어가 있습니다 . 일반적으로 이러한 언어를 사용하면 유형이있는 표현식에 주석을 달 수 있으며 해당 유형은 런타임 에 표현식 의 런타임 유형 과 비교하여 검사 됩니다 .
Jörg W Mittag

단지 정밀도 : 타입 시스템은 암시 적이거나 명시 적이 지 않습니다. 이것은 유형 유추에 관한 것입니다. 이는 본질적으로 다른 (때로는 지정되지 않은) 구문에서 유형 시스템에 유효한 용어를 생성하는 방법입니다.
Eduardo Pareja Tobes

좋은 대답이지만 명목 대 구조적 타이핑은 다루지 않습니다. 편집은 좋을 것입니다.
lunchmeat317 7

7
  • 정적 대 동적은 유형을 확인하는 시점을 나타냅니다 (컴파일 시간 또는 실행 시간에 다소)

  • 공칭 대 구조는 두 유형이 동일한 것으로 간주되는시기를 나타냅니다.

(그리고 변형이 있지만 가장 잘 알려진 것은 오리 타이핑이라고 알려진 전체 유형 대신 사용되는 것을 고려하는 구조적 타이핑 변형입니다.)

네 가지 조합 (정적 공칭, 정적 구조, 동적 공칭, 동적 구조)이 가능하며 언어는 순전히 한 클래스가 아니지만 다른 측면에있는 측면을 가지고 있습니다.

예를 들어, C ++의 타입 시스템은 정적이며, 대부분 명목이지만 템플릿을 고려할 때 구조적입니다 (그리고 C ++의 개념과 관련된 문제의 일부를 오리 타이핑에서 전체 형태의 구조 타이핑에 이르기까지의 갈등으로 간주 할 수 있습니다) 명목 입력을 원하시는 분). 그리고 클래스와 상속을 사용하면 어떤 경우에는 동적이고 명목상의 타이핑을 사용할 수 있습니다.

다이나믹 타입 시스템이 구조적 타이핑을 사용하지만 CLOS를 명목상의 측면으로 사용하는 언어


1

구조 : 유형 호환성은 유형 구조를 기반으로합니다 (예 : 2 개의 변수가 이름은 다르지만 동일한 구조를 가진 구조체 유형 인 경우 C에서 유형은 호환 가능).

일반적으로 그렇지 않습니다. 구조적 타이핑이란 의 인터페이스를 만족시킬 수 있는지 여부 B의 하위 유형을 의미합니다 . 이것은 일반적으로 같은 이름을 가진 멤버를 갖는 것을 의미합니다. 메모리에서 동일한 구조가 아닙니다.AA

이는 선언시 수퍼 유형을 지정해야하는 명목 유형과 다릅니다.


1

동적 및 정적 유형 시스템의 (실제로 세분화 된) 시스템의 차이점에 대해 가장 잘 설명 한 것은 Bob Harper 의이 블로그 게시물에 있습니다.

주요 요점은 다음과 같이 요약 될 수 있습니다.

  • 동적 언어는 한 가지 유형의 정적 언어입니다.

1
연결이 나빠질 수 있습니다. 블로그에서 최신 정보를 보더라도 기사의 가장 관련성있는 부분을 인용하여 후손을 위해 보존해야합니다.
Doval

2
확실한. 나는이 경우에 추가 된 문장 내가 :) 충분하다고 생각
에두아르도 파레 Tobes에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.