엄격한 타이핑보다 동적 타이핑이 더 좋습니다. 동적 타이핑이란 무엇입니까? "강한" 타이핑과 "약한" 타이핑으로 구분

입력 - 정보 개체에 유형을 할당합니다.

가장 일반적인 기본 데이터 유형은 다음과 같습니다.

  • 숫자
  • 상징적
  • 논리적

데이터 유형 시스템의 주요 기능:

  • 보안
    각 작업은 의도된 유형의 인수를 정확히 수신하는지 확인하기 위해 검사됩니다.
  • 최적화
    유형에 따라 효율적인 저장 방법과 이를 처리하는 알고리즘이 선택됩니다.
  • 선적 서류 비치
    프로그래머의 의도가 강조됩니다.
  • 추출
    상위 수준 데이터 유형을 사용하면 프로그래머는 값을 비트 모음이 아닌 상위 수준 엔터티로 생각할 수 있습니다.

분류

프로그래밍 언어 유형에는 여러 가지 분류가 있지만 주요 분류는 3가지뿐입니다.

정적/동적 타이핑

정적 - 유형 일관성의 할당 및 확인은 컴파일 단계에서 수행됩니다. 데이터 유형은 특정 값이 아닌 변수와 연결됩니다. 정적 타이핑을 사용하면 컴파일 단계에서 거의 사용되지 않는 프로그램 로직 분기에서 발생한 타이핑 오류를 찾을 수 있습니다.

동적 타이핑은 정적 타이핑의 반대입니다. 동적 타이핑에서는 프로그램 실행 중에 모든 유형이 발견됩니다.

동적 타이핑을 사용하면 타이핑 오류가 발생할 가능성이 높아지더라도 더 유연한 소프트웨어를 만들 수 있습니다. 단위 테스트는 동적 형식 프로그래밍 언어로 소프트웨어를 개발할 때 특히 중요합니다. 단위 테스트는 거의 사용되지 않는 프로그램 논리 분기에서 입력 오류를 찾는 유일한 방법이기 때문입니다.

동적 타이핑

Var LuckyNumber = 777; var siteName = "Tyapk"; // 숫자를 가정하고 문자열을 씁니다. varwrongNumber = "999";

정적 타이핑

LuckyNumber: 숫자 = 777; let siteName: string = "Tyapk"; // 오류가 발생합니다. letwrongNumber: number = "999";

  • 정적: Java, C#, TypeScript.
  • 동적: Python, Ruby, JavaScript.

명시적/암시적 유형 지정.

명시적 유형 언어는 새 변수/함수/해당 인수의 유형을 명시적으로 지정해야 한다는 점에서 다릅니다. 따라서 암시적 타이핑을 사용하는 언어는 이 작업을 컴파일러/인터프리터에게 맡깁니다. 명시적 타이핑은 암시적 타이핑의 반대입니다.

명시적 유형 지정에는 사용된 각 변수에 대한 명시적 유형 선언이 필요합니다. 이러한 유형의 타이핑은 정적 타이핑의 특별한 경우입니다. 각 변수의 유형은 컴파일 타임에 결정됩니다.

암시적 타이핑

stringVar = "777" + 99; // "77799"를 얻습니다.

명시적 타이핑(JS와 유사한 가상 언어)

잘못StringVar = "777" + 99; // 오류가 발생합니다. let stringVar = "777" + String(99); // "77799"를 얻습니다.

강력/강하지 않은 타이핑

강한/약한 타이핑이라고도 합니다. 엄격한 유형 지정을 사용하면 유형이 "한 번에" 할당됩니다. 엄격하지 않은 유형 지정을 사용하면 프로그램 실행 중에 유형이 변경될 수 있습니다.

강력한 유형의 언어는 변수의 데이터 유형 변경을 금지하고 명시적인 데이터 유형 변환만 허용합니다. 강력한 유형 지정은 언어가 표현식에 서로 다른 유형을 혼합하는 것을 허용하지 않고 자동 암시적 변환을 수행하지 않는다는 점에서 구별됩니다. 예를 들어 문자열에서 숫자를 뺄 수 없습니다. 약한 유형의 언어는 정밀도 손실이 발생하거나 변환이 모호하더라도 자동으로 많은 암시적 변환을 수행합니다.

강력한 타이핑(JS와 유사한 가상 언어)

잘못된 번호 = 777; 잘못된 번호 = 잘못된 번호 + "99"; // 숫자 변수에 문자열이 추가되었다는 오류가 발생합니다.wrongNumber let trueNumber = 777 + Number("99"); // 876을 얻습니다.

엄격하지 않은 유형 지정(js의 경우와 동일)

잘못된 번호 = 777; 잘못된 번호 = 잘못된 번호 + "99"; // 문자열 "77799"를 얻었습니다.

  • 엄격함: Java, Python, Haskell, Lisp.
  • 엄격하지 않음: C, JavaScript, Visual Basic, PHP.

이 기사에는 동적 타이핑을 나쁘게, Lisp를 유형 없는 언어, C를 강력한 유형의 언어라고 부르지 않기 위해 타이핑에 대해 알아야 할 최소한의 사항이 포함되어 있습니다.

정식 버전에는 모든 유형의 타이핑에 대한 자세한 설명, 코드 예제, 인기 있는 프로그래밍 언어에 대한 링크 및 예시 사진이 포함되어 있습니다.

먼저 기사의 짧은 버전을 읽어보고, 원하는 경우 전체 버전을 읽어 보시기 바랍니다.

짧은 버전

타이핑에 따라 프로그래밍 언어는 일반적으로 타입이 있는 언어와 타입이 없는(타입이 없는) 두 개의 큰 캠프로 나뉩니다. 첫 번째에는 C, Python, Scala, PHP 및 Lua가 포함되고 두 번째에는 어셈블리 언어인 Forth 및 Brainfuck이 포함됩니다.

"무타입 타이핑"은 본질적으로 플러그처럼 단순하기 때문에 더 이상 다른 유형으로 분류되지 않습니다. 그러나 입력된 언어는 몇 가지 더 겹치는 범주로 나뉩니다.

  • 정적/동적 타이핑. 정적은 변수와 함수의 최종 유형이 컴파일 타임에 설정된다는 사실로 정의됩니다. 저것들. 컴파일러는 이미 어떤 유형이 어디에 있는지 100% 확신합니다. 동적 타이핑에서는 프로그램 실행 중에 모든 유형이 발견됩니다.

    예:
    정적: C, 자바, C#;
    동적: Python, JavaScript, Ruby.

  • 강한/약한 타이핑(때때로 강한/느슨한 타이핑이라고도 함). 강력한 유형 지정은 언어가 표현식에서 다양한 유형의 혼합을 허용하지 않고 자동 암시적 변환을 수행하지 않는다는 점에서 구별됩니다. 예를 들어 문자열에서 집합을 뺄 수 없습니다. 약한 유형의 언어는 정밀도 손실이 발생하거나 변환이 모호하더라도 자동으로 많은 암시적 변환을 수행합니다.

    예:
    강력함: Java, Python, Haskell, Lisp;
    약함: C, JavaScript, Visual Basic, PHP.

  • 명시적/암시적 유형 지정. 명시적 유형 언어는 새 변수/함수/해당 인수의 유형을 명시적으로 지정해야 한다는 점에서 다릅니다. 따라서 암시적 타이핑을 사용하는 언어는 이 작업을 컴파일러/인터프리터에게 맡깁니다.

    예:
    명시적: C++, D, C#
    암시적: PHP, Lua, JavaScript

또한 이러한 범주는 모두 중복됩니다. 예를 들어 C 언어에는 정적 약한 명시적 유형 지정이 있고 Python 언어에는 동적 강력한 암시적 유형 지정이 있습니다.

그러나 정적 타이핑과 동적 타이핑이 동시에 가능한 언어는 없습니다. 앞을 내다 보면 내가 여기에 누워 있다고 말할 것입니다. 실제로 존재하지만 이에 대해서는 나중에 자세히 설명합니다.

상세 버전

짧은 버전이 충분하지 않다면 괜찮습니다. 내가 자세하게 쓴 게 괜히 있는 게 아니지? 가장 중요한 것은 모든 유용하고 흥미로운 정보를 짧은 버전에 넣는 것이 불가능했으며 자세한 정보는 모든 사람이 긴장하지 않고 읽기에는 너무 길다는 것입니다.

무형식 타이핑

유형이 없는 프로그래밍 언어에서 모든 엔터티는 단순히 다양한 길이의 비트 시퀀스로 간주됩니다.

유형 없는 타이핑은 일반적으로 저수준 언어(어셈블리 언어, Forth)와 난해한 언어(Brainfuck, HQ9, Piet)에 내재되어 있습니다. 그러나 단점과 함께 몇 가지 장점도 있습니다.

장점
  • 매우 낮은 수준에서 작성할 수 있으며 컴파일러/인터프리터는 유형 검사를 방해하지 않습니다. 모든 유형의 데이터에 대해 자유롭게 작업을 수행할 수 있습니다.
  • 결과 코드는 일반적으로 더 효율적입니다.
  • 지침의 투명성. 언어를 알고 있다면 일반적으로 이 코드나 해당 코드가 무엇인지 의심할 여지가 없습니다.
결함
  • 복잡성. 목록, 문자열, 구조체 등 복잡한 값을 표현해야 하는 경우가 많습니다. 불편을 끼칠 수 있습니다.
  • 수표가 부족합니다. 기호에서 배열에 대한 포인터를 빼는 것과 같은 의미 없는 작업은 완전히 정상적인 것으로 간주되며 미묘한 오류가 발생합니다.
  • 낮은 수준의 추상화. 복잡한 데이터 유형으로 작업하는 것은 숫자로 작업하는 것과 다르지 않으며, 이는 물론 많은 어려움을 야기합니다.
강력한 무형식 타이핑?

예, 존재합니다. 예를 들어, 어셈블리 언어(x86/x86-64 아키텍처의 경우 다른 것은 모르겠습니다)에서 rax 레지스터(64비트)의 데이터를 cx 레지스터(16비트)로 로드하려고 하면 프로그램을 어셈블할 수 없습니다. .

mov cx, eax ; 조립시간 오류

그럼 어셈블러에는 여전히 타이핑이 있다는 것이 밝혀졌나요? 나는 이러한 수표만으로는 충분하지 않다고 생각합니다. 물론 귀하의 의견은 귀하에게만 달려 있습니다.

정적 및 동적 타이핑

정적 유형 지정과 동적 유형 지정을 구별하는 가장 중요한 점은 모든 유형 검사가 런타임이 아닌 컴파일 타임에 수행된다는 것입니다.

어떤 사람들은 정적 타이핑이 너무 제한적이라고 생각할 수도 있습니다(사실 그렇습니다. 그러나 이것은 일부 기술의 도움으로 오랫동안 제거되었습니다). 어떤 사람들은 동적 타이핑 언어가 불장난을 하고 있다고 말하는데, 어떤 특징이 이 언어를 돋보이게 할까요? 두 종 모두 실제로 존재할 가능성이 있습니까? 그렇지 않다면 정적 및 동적으로 유형이 지정되는 언어가 왜 그렇게 많습니까?

그것을 알아 봅시다.

정적 유형 지정의 이점
  • 유형 검사는 컴파일 단계에서 한 번만 발생합니다. 즉, 숫자를 문자열로 나누려고 하는지(그리고 오류가 발생하는지 변환을 수행하는지) 끊임없이 알아낼 필요가 없습니다.
  • 실행 속도. 이전 시점에서 정적으로 유형이 지정된 언어는 거의 항상 동적으로 유형이 지정된 언어보다 빠르다는 것이 분명합니다.
  • 일부 추가 조건에서는 컴파일 단계에서 이미 잠재적인 오류를 감지할 수 있습니다.
동적 타이핑의 이점
  • 범용 컬렉션 생성 용이성 - 모든 것과 모든 사람의 힙(이러한 필요성은 거의 발생하지 않지만 동적 타이핑이 발생하면 도움이 될 것입니다).
  • 일반화된 알고리즘 설명의 편의성(예: 정수 목록뿐만 아니라 실수 목록, 심지어 문자열 목록에서도 작동하는 배열 정렬)
  • 배우기 쉬움 - 동적 유형 언어는 일반적으로 프로그래밍을 시작하는 데 매우 좋습니다.

일반화된 프로그래밍

좋아요, 동적 타이핑에 대한 가장 중요한 주장은 일반 알고리즘을 설명하는 편리함입니다. 문제를 상상해 봅시다. 정수 배열, 실수 배열, 문자 배열 등 여러 배열(또는 목록)을 검색하는 함수가 필요합니다.

어떻게 해결할까요? 3가지 다른 언어로 문제를 해결해 보겠습니다. 하나는 동적 타이핑이고 두 개는 정적 타이핑입니다.

가장 간단한 검색 알고리즘 중 하나인 무차별 대입을 사용하겠습니다. 이 함수는 검색 중인 요소, 배열(또는 목록) 자체를 수신하고 요소의 인덱스를 반환하거나 요소를 찾을 수 없는 경우 - (-1)을 반환합니다.

동적 솔루션(Python):

Def find(required_element, list): for (index, element) in enumerate(list): if element == 필수_element: return index return (-1)

보시다시피 모든 것이 간단하며 목록에 숫자, 목록 또는 기타 배열이 포함될 수 있다는 사실에는 문제가 없습니다. 매우 좋은. 더 나아가서 C에서 동일한 문제를 해결해 보세요!

정적 용액(C):

Unsigned int find_int(int 필수_요소, int 배열, unsigned int 크기) ( for (unsigned int i = 0; i< size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_float(float required_element, float array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_char(char required_element, char array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); }

글쎄, 각 함수는 개별적으로 Python 버전과 유사하지만 왜 세 개가 있습니까? 정적 프로그래밍이 정말 손실되었나요?

예, 아니오. 여러 가지 프로그래밍 기술이 있는데, 그 중 하나를 이제 살펴보겠습니다. 이를 일반 프로그래밍이라고 하며 C++ 언어는 이를 매우 잘 지원합니다. 새 버전을 살펴보겠습니다.

정적 솔루션(일반 프로그래밍, C++):

주형 unsigned int find(T 필수 요소, std::벡터 배열) ( for (unsigned int i = 0; i< array.size(); ++i) if (required_element == array[i]) return i; return (-1); }

괜찮은! Python 버전보다 훨씬 더 복잡해 보이지 않으며 많은 작성이 필요하지 않습니다. 또한 문제를 해결하는 데 필요한 3개 어레이뿐만 아니라 모든 어레이에 대한 구현을 얻었습니다!

이 버전은 우리에게 꼭 필요한 것 같습니다. 정적 타이핑의 장점과 동적 타이핑의 장점 중 일부를 모두 얻습니다.

이것이 가능하다는 것은 좋은 일이지만, 더 좋을 수도 있습니다. 첫째, 일반화된 프로그래밍이 더 편리하고 아름다울 수 있습니다(예: Haskell 언어 사용). 둘째, 일반화된 프로그래밍 외에도 다형성(결과가 더 나쁠 수 있음), 함수 오버로딩(비슷한) 또는 매크로를 사용할 수도 있습니다.

역학의 정적

또한 많은 정적 언어가 동적 타이핑을 허용한다는 점도 언급해야 합니다. 예를 들면 다음과 같습니다.

  • C#은 동적 의사 유형을 지원합니다.
  • F#은 동적 유형 지정을 모방할 수 있는 ? 연산자 형식의 설탕 구문을 지원합니다.
  • Haskell - 동적 타이핑은 Data.Dynamic 모듈에서 제공됩니다.
  • Delphi - 특별한 Variant 유형을 통해.

또한 일부 동적 유형 지정 언어를 사용하면 정적 유형 지정을 활용할 수 있습니다.

  • Common Lisp - 유형 선언.
  • Perl - 버전 5.6 이후로는 상당히 제한적입니다.

강한 타이핑과 약한 타이핑

강력한 유형의 언어는 서로 다른 유형의 엔터티가 표현식에 혼합되는 것을 허용하지 않으며 자동 변환을 수행하지 않습니다. "강력한 형식의 언어"라고도 합니다. 이에 대한 영어 용어는 강한 타이핑입니다.

반대로 약한 유형의 언어는 프로그래머가 하나의 표현식에 다양한 유형을 혼합하도록 권장하며 컴파일러 자체는 모든 것을 단일 유형으로 줄입니다. "느슨한 형식의 언어"라고도 합니다. 이에 대한 영어 용어는 약한 타이핑입니다.

약한 타이핑은 종종 완전히 잘못된 동적 타이핑과 혼동됩니다. 동적 유형 언어는 약한 유형 또는 강력한 유형일 수 있습니다.

그러나 엄격한 타이핑을 중요시하는 사람은 거의 없습니다. 언어가 정적으로 입력되면 컴파일할 때 많은 잠재적인 오류를 발견할 수 있다고 흔히 말합니다. 그들은 당신에게 거짓말을 하고 있습니다!

언어에는 강력한 타이핑도 있어야 합니다. 실제로 컴파일러가 오류를 보고하는 대신 단순히 숫자에 문자열을 추가하거나 더 나쁜 경우 한 배열에서 다른 문자열을 빼면 유형의 모든 "검사"가 컴파일 시 수행된다는 것이 우리에게 무슨 소용이 있습니까? 단계? 맞습니다. 약한 정적 타이핑은 강력한 동적 타이핑보다 더 나쁩니다! (뭐, 그건 내 생각이다)

그렇다면 약한 타이핑에는 전혀 이점이 없습니까? 이렇게 보일 수도 있겠지만, 내가 강한 타이핑을 열렬히 지지한다는 사실에도 불구하고 약한 타이핑에도 장점이 있다는 점에는 동의할 수밖에 없습니다.

어떤 것을 알고 싶으십니까?

강력한 타이핑의 이점
  • 신뢰성 - 잘못된 동작 대신 예외 또는 컴파일 오류가 발생합니다.
  • 속도 - 꽤 비용이 많이 들 수 있는 숨겨진 변환 대신 강력한 타이핑을 사용하여 명시적으로 작성해야 하며, 이로 인해 프로그래머는 최소한 이 코드 조각이 느릴 수 있다는 것을 알 수 있습니다.
  • 프로그램 작동 방식 이해 - 다시 말하지만, 프로그래머는 암시적 유형 캐스팅 대신 모든 것을 직접 작성합니다. 즉, 문자열과 숫자를 비교하는 일은 마술이 아니라 저절로 발생하지 않는다는 것을 대략적으로 이해합니다.
  • 확실성 - 손으로 변환을 작성할 때 무엇을 변환하고 무엇으로 변환하는지 정확히 알 수 있습니다. 또한 이러한 변환으로 인해 정밀도가 떨어지고 잘못된 결과가 발생할 수 있다는 점도 항상 알고 있어야 합니다.
약한 타이핑의 이점
  • 혼합 표현식 사용의 편리성(예: 정수와 실수)
  • 타이핑을 추상화하고 작업에 집중합니다.
  • 항목의 간결함.

좋아요, 우리는 그것을 알아냈습니다. 약한 타이핑에도 장점이 있다는 것이 밝혀졌습니다! 약한 타이핑의 장점을 강한 타이핑으로 전환할 수 있는 방법이 있나요?

두 개도 있다는 것이 밝혀졌습니다.

명확한 상황에서 데이터 손실 없이 암시적 유형 캐스팅

와... 꽤 긴 말이군요. 이를 "제한된 암시적 변환"으로 더 단축하겠습니다. 그렇다면 명확한 상황과 데이터 손실은 무엇을 의미합니까?

모호하지 않은 상황은 본질이 즉각적으로 명확한 변형이나 작업입니다. 예를 들어 두 개의 숫자를 추가하는 것은 명확한 상황입니다. 그러나 숫자를 배열로 변환하는 것은 그렇지 않습니다. 아마도 한 요소의 배열이 생성될 것입니다. 아마도 이러한 길이의 배열은 기본적으로 요소로 채워지고 숫자는 문자열로 변환된 다음 배열로 변환될 것입니다. 문자).

데이터를 잃는 것이 훨씬 더 쉽습니다. 실수 3.5를 정수로 변환하면 데이터의 일부가 손실됩니다(사실 이 연산도 모호합니다. 반올림은 어떻게 수행됩니까? 위로? 아래로? 분수 부분을 버리나요?).

모호한 상황에서의 변환과 데이터 손실이 있는 변환은 매우 나쁩니다. 프로그래밍에서 이보다 더 나쁜 것은 없습니다.

내 말을 믿을 수 없다면 PL/I 언어를 공부하거나 사양을 찾아보세요. 모든 데이터 유형 간 변환에 대한 규칙이 있습니다! 이건 그냥 지옥이야!

좋아요, 제한된 암시적 변환에 대해 기억해 봅시다. 그런 언어도 있나요? 예, 예를 들어 Pascal에서는 정수를 실수로 변환할 수 있지만 그 반대는 불가능합니다. C#, Groovy 및 Common Lisp에도 유사한 메커니즘이 있습니다.

좋아, 나는 강력한 언어에서 약한 타이핑의 몇 가지 장점을 얻을 수 있는 방법이 아직 있다고 말했습니다. 그리고 그렇습니다. 그것은 존재하며 생성자 다형성이라고 불립니다.

훌륭한 하스켈 언어의 예를 들어 설명하겠습니다.

다형성 생성자는 숫자 리터럴을 사용할 때 안전한 암시적 변환이 가장 자주 필요하다는 관찰에서 탄생했습니다.

예를 들어, pi + 1 표현식에서 pi + 1.0 또는 pi + float(1) 을 쓰고 싶지 않을 것입니다. 나는 단지 pi + 1을 쓰고 싶습니다!

그리고 이것은 리터럴 1에 구체적인 유형이 없기 때문에 Haskell에서 수행됩니다. 그것은 전체도 아니고 실제도 아니며 복잡하지도 않습니다. 그것은 단지 숫자일 뿐입니다!

결과적으로 간단한 함수 sum x y 를 작성하고 x에서 y까지의 모든 숫자(1씩 증분)를 곱하면 한 번에 여러 버전을 얻게 됩니다. 정수의 합, 실수의 합, 유리수의 합, 복소수의 합 그리고 여러분이 직접 정의한 모든 숫자 유형의 합계도 계산할 수 있습니다.

물론 이 기술은 숫자 리터럴이 포함된 혼합 표현식을 사용할 때만 비용을 절감하며 이는 빙산의 일각에 불과합니다.

따라서 가장 좋은 해결책은 강한 타이핑과 약한 타이핑 사이의 경계에서 균형을 맞추는 것이라고 말할 수 있습니다. 하지만 아직 완벽한 균형을 이루는 언어는 없기 때문에 약한 유형의 언어(예: C, JavaScript, Lua, PHP)보다는 강력한 유형의 언어(예: Haskell, Java, C#, Python)에 더 의지합니다.

명시적 및 암시적 입력

명시적으로 유형이 지정된 언어에서는 프로그래머가 선언하는 모든 변수 및 함수의 유형을 지정해야 합니다. 이에 대한 영어 용어는 명시적 타이핑입니다.

반면에 암시적으로 유형이 지정된 언어는 유형을 잊어버리고 유형을 추론하는 작업을 컴파일러나 해석기에 맡기도록 권장합니다. 이에 대한 영어 용어는 암시적 타이핑입니다.

처음에는 암시적 유형 지정이 동적과 동일하고 명시적 유형 지정이 정적과 동일하다고 생각할 수 있지만 나중에는 그렇지 않다는 것을 알게 됩니다.

각 유형마다 장점이 있나요? 그리고 또 이들의 조합이 있나요? 두 가지 방법을 모두 지원하는 언어가 있나요?

명시적 입력의 이점
  • 각 함수에 서명(예: int add(int, int))이 있으면 함수가 수행하는 작업을 쉽게 확인할 수 있습니다.
  • 프로그래머는 특정 변수에 어떤 유형의 값을 저장할 수 있는지 즉시 기록하므로 이를 기억할 필요가 없습니다.
암시적 유형 지정의 이점
  • 단축 표기법 - def add(x, y) 는 int add(int x, int y) 보다 분명히 짧습니다.
  • 변화에 대한 저항. 예를 들어, 함수에서 임시 변수가 입력 인수와 동일한 유형인 경우 명시적으로 유형이 지정된 언어에서는 입력 인수의 유형을 변경할 때 임시 변수의 유형도 변경해야 합니다.

좋아요, 두 접근 방식 모두 장단점이 있다는 것은 분명합니다(누가 또 예상했겠습니까?). 따라서 이 두 접근 방식을 결합하는 방법을 찾아보겠습니다.

선택에 의한 명시적 입력

기본적으로 암시적 타이핑이 가능한 언어와 필요한 경우 값 유형을 지정할 수 있는 기능이 있습니다. 번역기는 실제 유형의 표현식을 자동으로 출력합니다. 이러한 언어 중 하나는 Haskell입니다. 명확성을 위해 간단한 예를 들어 보겠습니다.

명시적 유형 지정 없이 add (x, y) = x + y -- 명시적 유형 지정 add:: (Integer, Integer) -> Integer add (x, y) = x + y

참고: 저는 의도적으로 커링되지 않은 함수를 사용했으며 더 일반적인 add::(Num a) -> a -> a -> a 대신 의도적으로 개인 서명을 작성했습니다. 하스켈 구문을 설명하지 않고 아이디어를 보여주고 싶었습니다.

흠. 보시다시피 매우 훌륭하고 짧습니다. 함수를 작성하려면 공백을 포함하여 한 줄에 18자만 입력하면 됩니다!

그러나 자동 유형 추론은 상당히 복잡한 일이며 Haskell과 같은 멋진 언어에서도 때때로 실패합니다. (예는 단형성 제약 조건입니다)

기본적으로 명시적 타이핑이 있고 필요한 경우 암시적 타이핑이 있는 언어가 있나요? 범죄자
확신하는.

선택에 의한 암시적 입력

C++11(이전에는 C++0x라고 함)이라는 새로운 C++ 언어 표준에는 컴파일러가 컨텍스트를 기반으로 형식을 추론할 수 있도록 하는 auto 키워드가 도입되었습니다.

비교해 보겠습니다. // unsigned 유형을 수동으로 지정 int a = 5; 부호 없는 int b = a + 3; // unsigned int a = 5 유형의 자동 출력; 자동 b = a + 3;

나쁘지 않다. 하지만 기록은 크게 줄지 않았다. 반복자가 포함된 예를 살펴보겠습니다(이해하지 못하더라도 걱정하지 마세요. 가장 중요한 점은 자동 출력 덕분에 녹음이 크게 줄어든다는 것입니다).

// std::Vector 유형을 수동으로 지정 vec = 무작위벡터(30); for (std::Vector::const_iterator it = vec.cbegin(); ...) ( ... ) // 자동 유형 추론 auto vec = randomVector (서른); for (auto it = vec.cbegin(); ...) ( ... )

우와! 이것이 약어입니다. 좋아, 하지만 반환 유형이 인수 유형에 따라 달라지는 Haskell과 같은 작업을 수행하는 것이 가능합니까?

그리고 대답은 '예'입니다. auto와 결합된 decltype 키워드 덕분입니다.

// 수동 유형 int Divide(int x, int y) ( ... ) // 자동 유형 추론 auto Divide(int x, int y) -> decltype(x / y) ( ... )

이러한 형태의 표기법은 별로 좋아 보이지 않을 수 있지만 일반 프로그래밍(템플릿/제네릭)과 결합하면 암시적 유형 지정 또는 자동 유형 추론이 놀라운 효과를 발휘합니다.

이 분류에 따른 일부 프로그래밍 언어

나는 인기있는 언어의 작은 목록을 제공하고 "타이핑"의 각 범주로 어떻게 나뉘는지 쓸 것입니다.

JavaScript - 동적 / 약함 / 암시적 Ruby - 동적 / 강력 / 암시적 Python - 동적 / 강력 / 암시적 Java - 정적 / 강력 / 명시적 PHP - 동적 / 약 / 암시적 C - 정적 / 약 / 명시적 C++ - 정적 / 준강함 / 명시적 Perl - 동적 / 약함 / 암시적 Objective-C - 정적 / 약함 / 명시적 C# - 정적 / 강력 / 명시적 Haskell - 정적 / 강력 / 암시적 Common Lisp - 동적 / 강력 / 암시적

특히 CL, PHP 및 Obj-C에서 실수를 저질렀을 수도 있습니다. 일부 언어에 대해 다른 의견이 있으면 의견을 적어주세요.

결론

좋아요. 곧 가벼워질 것이고 타이핑에 대해서는 더 이상 할 말이 없다는 느낌이 듭니다. 아 어떻게요? 주제가 끝이 없나요? 말하지 않은 것이 많이 남아 있습니까? 댓글로 유용한 정보를 공유해주세요.

모든 것이 매우 간단합니다. 호텔과 개인 아파트의 차이와 같습니다.

그곳에 등록된 사람들만 아파트에 거주합니다. 예를 들어 Sidorov 가족이 그 안에 살고 있다면 Pupkin 가족은 우리 삶을 위해 그곳에서 살 수 없습니다. 동시에 Petya Sidorov는이 아파트에 살 수 있고 Grisha Sidorov는 그곳으로 이사 할 수 있습니다 (때로는 동시에 거기에 살 수도 있습니다. 이것은 배열입니다). 이것은 정적 타이핑입니다.

Sidorov 가족은 한 번에 호텔에 살 수 있습니다. 항상 거기에 등록할 필요도 없습니다. 그런 다음 그들은 그곳을 떠날 것이고 Pupkins는 그곳으로 이동할 것입니다. 그리고 Kuznetsovs. 그리고 다른 사람. 이것은 동적 타이핑입니다.

프로그래밍으로 돌아가면 첫 번째 경우(정적 타이핑)는 C, C++, C#, Java 및 기타 언어에서 발견됩니다. 처음으로 변수에 값을 할당하기 전에 변수에 저장할 내용(정수, 부동 소수점 숫자, 문자열 등)을 지정해야 합니다. ( Sidorovs는 이 아파트에 살 것입니다). 반면 동적 타이핑에는 이것이 필요하지 않습니다. 값을 할당하면 변수에 해당 유형( Pupkin 가족의 Vasya Pupkin이 이제 이 호텔 방에 살고 있습니다.). 이는 PHP, Python 및 JavaScript와 같은 언어에서 발견됩니다.

두 접근 방식 모두 장점과 단점이 있습니다. 어느 것이 더 좋고 더 나쁜지는 해결되는 문제에 따라 다릅니다. 예를 들어 Wikipedia에서 더 자세히 읽을 수 있습니다.

정적 타이핑을 사용하면 프로그램을 작성하고 알고리즘을 개발할 때 변수의 유형을 정확히 알고 이를 고려합니다. 저것들. 변수 G가 4바이트 부호 없는 정수라고 말하면 알고리즘에서는 항상 4바이트 부호 없는 정수가 됩니다(있는 경우 이를 명시적으로 변환하거나 변환기가 특정 형식으로 변환하는 방법을 알아야 합니다). 다양한 상황이 있지만 주로 유형 불일치가 있는 경우 이는 알고리즘의 오류이며 컴파일러는 최소한 경고합니다.) 정적 경우에는 "Vasya the Fool"이라는 문자열을 숫자에 넣을 수 없습니다. 변수를 사용하기 전에 "숫자가 있는지"를 결정하는 추가 검사가 필요하지 않으며 프로그램에 입력할 때 또는 알고리즘 자체에서 요구하는 대로 데이터의 모든 정확성을 수행합니다.

동적 타이핑을 사용하면 동일한 변수의 유형이 일반적으로 사용자에게 알려지지 않고 프로그램 실행 중에 이미 변경될 수 있으며 이를 고려하면 유형 불일치로 인한 알고리즘의 잠재적 오류에 대해 아무도 경고하지 않습니다. (알고리즘을 개발할 때 G가 정수라고 가정하고 사용자가 부동 소수점 숫자 또는 더 나쁜 문자열을 입력했거나 산술 연산 후에 정수 대신 부동 소수점이 있었다고 가정했습니다. , 그리고 다음 단계에서는 비트 연산을 사용해 볼 것입니다...) 반면에 많은 작은 것들에 대해 걱정할 필요가 없습니다.

전제 조건

엄격한 입력은 다음 필수 조건이 충족됨을 의미합니다.

  1. 언어의 모든 데이터 객체(변수, 상수, 표현식)는 항상 엄격하게 정의된 유형을 가지며, 이는 프로그램 컴파일 시 고정되거나(정적 유형 지정) 런타임 시 결정됩니다(동적 유형 지정).
  2. 변수와 정확히 동일한 데이터 유형을 가진 값만 변수에 할당할 수 있으며, 매개변수 전달 및 함수 결과 반환에도 동일한 제한이 적용됩니다.
  3. 각 작업에는 엄격하게 정의된 유형의 매개변수가 필요합니다.
  4. 암시적 유형 변환은 허용되지 않습니다. 즉, 변환기는 변수, 매개변수, 함수 또는 연산에 대해 선언된 유형 값이 아닌 유형의 값을 사용하려는 모든 시도를 구문 오류로 처리합니다.

엄격한 입력 요구 사항을 엄격하게 준수하면 값 구성과 허용되는 작업이 동일한 데이터 유형이라도 호환되지 않습니다. 프로그램이 한 데이터 유형의 값을 다른 유형의 변수에 할당해야 하는 경우 이를 수행할 수 있지만 이는 일반적으로 프로그래밍 언어의 일부인 특별한 유형 변환 작업을 명시적으로 적용해야만 가능합니다. 공식적으로는 아니지만 표준 라이브러리에서 제공됩니다).

프로그래밍 언어로 입력하기

연결

또한보십시오


위키미디어 재단. 2010.

다른 사전에 "강력한 타이핑"이 무엇인지 확인하십시오.

    데이터 유형은 프로그래밍 이론의 기본 개념입니다. 데이터 유형은 값 집합, 해당 값에 적용될 수 있는 작업 집합, 값 저장 및 작업 수행을 구현하는 방법을 정의합니다. 뭐든... ... 위키피디아

    데이터 타이핑 유형 안전성 유형 추론 동적 타이핑 정적 타이핑 강력한 타이핑 소프트 타이핑 종속 유형 오리 타이핑 주요 기사: 강력한 타이핑 동적 타이핑은 널리 사용되는 기술입니다... ... Wikipedia

    데이터 타이핑 유형 안전성 유형 추론 동적 타이핑 정적 타이핑 강력한 타이핑 소프트 타이핑 종속 유형 오리 타이핑 주요 기사: 강력한 타이핑 정적 타이핑은 널리 사용되는 기술입니다... ... Wikipedia

    동적 타이핑(Dynamic Typing)은 프로그래밍 언어나 명세 언어에서 널리 사용되는 기술로, 변수를 선언하는 순간이 아닌 값을 할당하는 순간에 변수가 타입과 연관되는 방식이다. 따라서 다양한 분야에서 ... Wikipedia

    데이터 타이핑 유형 안전성 유형 추론 동적 타이핑 정적 타이핑 강력한 타이핑 소프트 타이핑 종속 유형 오리 타이핑 프로그래밍의 유형 추론은 컴파일러 기능입니다... ... Wikipedia

    데이터 타이핑 유형 안전성 유형 추론 동적 타이핑 정적 타이핑 강력한 타이핑 소프트 타이핑 종속 유형 덕 타이핑 종속 유형, 컴퓨터 과학 및 논리에서 값에 의존하는 유형입니다. 부양가족... ... 위키피디아

    - (데이터 유형이라는 용어도 발견됨)은 프로그래밍 이론의 기본 개념입니다. 데이터 유형은 값 집합, 해당 값에 적용될 수 있는 작업 집합, 값 저장을 구현하는 방법 및... ... Wikipedia를 정의합니다.

    데이터 유형 내용 1 역사 2 정의 3 데이터 유형 사용의 필요성 ... Wikipedia

    이 용어에는 다른 의미도 있습니다. ML(의미)을 참조하세요. ML 의미: 다중 패러다임: 기능적, 명령적, 모듈식 등장: 1973년 저자: Robin Milner et al. University of Edinburgh ... Wikipedia

이 기사에는 동적 타이핑을 나쁘게, Lisp를 유형 없는 언어, C를 강력한 유형의 언어라고 부르지 않기 위해 타이핑에 대해 알아야 할 최소한의 사항이 포함되어 있습니다.

정식 버전에는 모든 유형의 타이핑에 대한 자세한 설명, 코드 예제, 인기 있는 프로그래밍 언어에 대한 링크 및 예시 사진이 포함되어 있습니다.

먼저 기사의 짧은 버전을 읽어보고, 원하는 경우 전체 버전을 읽어 보시기 바랍니다.

짧은 버전

타이핑에 따라 프로그래밍 언어는 일반적으로 타입이 있는 언어와 타입이 없는(타입이 없는) 두 개의 큰 캠프로 나뉩니다. 첫 번째에는 C, Python, Scala, PHP 및 Lua가 포함되고 두 번째에는 어셈블리 언어인 Forth 및 Brainfuck이 포함됩니다.

"무타입 타이핑"은 본질적으로 플러그처럼 단순하기 때문에 더 이상 다른 유형으로 분류되지 않습니다. 그러나 입력된 언어는 몇 가지 더 겹치는 범주로 나뉩니다.

  • 정적/동적 타이핑. 정적은 변수와 함수의 최종 유형이 컴파일 타임에 설정된다는 사실로 정의됩니다. 저것들. 컴파일러는 이미 어떤 유형이 어디에 있는지 100% 확신합니다. 동적 타이핑에서는 프로그램 실행 중에 모든 유형이 발견됩니다.

    예:
    정적: C, 자바, C#;
    동적: Python, JavaScript, Ruby.

  • 강한/약한 타이핑(때때로 강한/느슨한 타이핑이라고도 함). 강력한 유형 지정은 언어가 표현식에서 다양한 유형의 혼합을 허용하지 않고 자동 암시적 변환을 수행하지 않는다는 점에서 구별됩니다. 예를 들어 문자열에서 집합을 뺄 수 없습니다. 약한 유형의 언어는 정밀도 손실이 발생하거나 변환이 모호하더라도 자동으로 많은 암시적 변환을 수행합니다.

    예:
    강력함: Java, Python, Haskell, Lisp;
    약함: C, JavaScript, Visual Basic, PHP.

  • 명시적/암시적 유형 지정. 명시적 유형 언어는 새 변수/함수/해당 인수의 유형을 명시적으로 지정해야 한다는 점에서 다릅니다. 따라서 암시적 타이핑을 사용하는 언어는 이 작업을 컴파일러/인터프리터에게 맡깁니다.

    예:
    명시적: C++, D, C#
    암시적: PHP, Lua, JavaScript

또한 이러한 범주는 모두 중복됩니다. 예를 들어 C 언어에는 정적 약한 명시적 유형 지정이 있고 Python 언어에는 동적 강력한 암시적 유형 지정이 있습니다.

그러나 정적 타이핑과 동적 타이핑이 동시에 가능한 언어는 없습니다. 앞을 내다 보면 내가 여기에 누워 있다고 말할 것입니다. 실제로 존재하지만 이에 대해서는 나중에 자세히 설명합니다.

상세 버전

짧은 버전이 충분하지 않다면 괜찮습니다. 내가 자세하게 쓴 게 괜히 있는 게 아니지? 가장 중요한 것은 모든 유용하고 흥미로운 정보를 짧은 버전에 넣는 것이 불가능했으며 자세한 정보는 모든 사람이 긴장하지 않고 읽기에는 너무 길다는 것입니다.

무형식 타이핑

유형이 없는 프로그래밍 언어에서 모든 엔터티는 단순히 다양한 길이의 비트 시퀀스로 간주됩니다.

유형 없는 타이핑은 일반적으로 저수준 언어(어셈블리 언어, Forth)와 난해한 언어(Brainfuck, HQ9, Piet)에 내재되어 있습니다. 그러나 단점과 함께 몇 가지 장점도 있습니다.

장점
  • 매우 낮은 수준에서 작성할 수 있으며 컴파일러/인터프리터는 유형 검사를 방해하지 않습니다. 모든 유형의 데이터에 대해 자유롭게 작업을 수행할 수 있습니다.
  • 결과 코드는 일반적으로 더 효율적입니다.
  • 지침의 투명성. 언어를 알고 있다면 일반적으로 이 코드나 해당 코드가 무엇인지 의심할 여지가 없습니다.
결함
  • 복잡성. 목록, 문자열, 구조체 등 복잡한 값을 표현해야 하는 경우가 많습니다. 불편을 끼칠 수 있습니다.
  • 수표가 부족합니다. 기호에서 배열에 대한 포인터를 빼는 것과 같은 의미 없는 작업은 완전히 정상적인 것으로 간주되며 미묘한 오류가 발생합니다.
  • 낮은 수준의 추상화. 복잡한 데이터 유형으로 작업하는 것은 숫자로 작업하는 것과 다르지 않으며, 이는 물론 많은 어려움을 야기합니다.
강력한 무형식 타이핑?

예, 존재합니다. 예를 들어, 어셈블리 언어(x86/x86-64 아키텍처의 경우 다른 것은 모르겠습니다)에서 rax 레지스터(64비트)의 데이터를 cx 레지스터(16비트)로 로드하려고 하면 프로그램을 어셈블할 수 없습니다. .

mov cx, eax ; 조립시간 오류

그럼 어셈블러에는 여전히 타이핑이 있다는 것이 밝혀졌나요? 나는 이러한 수표만으로는 충분하지 않다고 생각합니다. 물론 귀하의 의견은 귀하에게만 달려 있습니다.

정적 및 동적 타이핑

정적 유형 지정과 동적 유형 지정을 구별하는 가장 중요한 점은 모든 유형 검사가 런타임이 아닌 컴파일 타임에 수행된다는 것입니다.

어떤 사람들은 정적 타이핑이 너무 제한적이라고 생각할 수도 있습니다(사실 그렇습니다. 그러나 이것은 일부 기술의 도움으로 오랫동안 제거되었습니다). 어떤 사람들은 동적 타이핑 언어가 불장난을 하고 있다고 말하는데, 어떤 특징이 이 언어를 돋보이게 할까요? 두 종 모두 실제로 존재할 가능성이 있습니까? 그렇지 않다면 정적 및 동적으로 유형이 지정되는 언어가 왜 그렇게 많습니까?

그것을 알아 봅시다.

정적 유형 지정의 이점
  • 유형 검사는 컴파일 단계에서 한 번만 발생합니다. 즉, 숫자를 문자열로 나누려고 하는지(그리고 오류가 발생하는지 변환을 수행하는지) 끊임없이 알아낼 필요가 없습니다.
  • 실행 속도. 이전 시점에서 정적으로 유형이 지정된 언어는 거의 항상 동적으로 유형이 지정된 언어보다 빠르다는 것이 분명합니다.
  • 일부 추가 조건에서는 컴파일 단계에서 이미 잠재적인 오류를 감지할 수 있습니다.
동적 타이핑의 이점
  • 범용 컬렉션 생성 용이성 - 모든 것과 모든 사람의 힙(이러한 필요성은 거의 발생하지 않지만 동적 타이핑이 발생하면 도움이 될 것입니다).
  • 일반화된 알고리즘 설명의 편의성(예: 정수 목록뿐만 아니라 실수 목록, 심지어 문자열 목록에서도 작동하는 배열 정렬)
  • 배우기 쉬움 - 동적 유형 언어는 일반적으로 프로그래밍을 시작하는 데 매우 좋습니다.

일반화된 프로그래밍

좋아요, 동적 타이핑에 대한 가장 중요한 주장은 일반 알고리즘을 설명하는 편리함입니다. 문제를 상상해 봅시다. 정수 배열, 실수 배열, 문자 배열 등 여러 배열(또는 목록)을 검색하는 함수가 필요합니다.

어떻게 해결할까요? 3가지 다른 언어로 문제를 해결해 보겠습니다. 하나는 동적 타이핑이고 두 개는 정적 타이핑입니다.

가장 간단한 검색 알고리즘 중 하나인 무차별 대입을 사용하겠습니다. 이 함수는 검색 중인 요소, 배열(또는 목록) 자체를 수신하고 요소의 인덱스를 반환하거나 요소를 찾을 수 없는 경우 - (-1)을 반환합니다.

동적 솔루션(Python):

Def find(required_element, list): for (index, element) in enumerate(list): if element == 필수_element: return index return (-1)

보시다시피 모든 것이 간단하며 목록에 숫자, 목록 또는 기타 배열이 포함될 수 있다는 사실에는 문제가 없습니다. 매우 좋은. 더 나아가서 C에서 동일한 문제를 해결해 보세요!

정적 용액(C):

Unsigned int find_int(int 필수_요소, int 배열, unsigned int 크기) ( for (unsigned int i = 0; i< size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_float(float required_element, float array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); } unsigned int find_char(char required_element, char array, unsigned int size) { for (unsigned int i = 0; i < size; ++i) if (required_element == array[i]) return i; return (-1); }

글쎄, 각 함수는 개별적으로 Python 버전과 유사하지만 왜 세 개가 있습니까? 정적 프로그래밍이 정말 손실되었나요?

예, 아니오. 여러 가지 프로그래밍 기술이 있는데, 그 중 하나를 이제 살펴보겠습니다. 이를 일반 프로그래밍이라고 하며 C++ 언어는 이를 매우 잘 지원합니다. 새 버전을 살펴보겠습니다.

정적 솔루션(일반 프로그래밍, C++):

주형 unsigned int find(T 필수 요소, std::벡터 배열) ( for (unsigned int i = 0; i< array.size(); ++i) if (required_element == array[i]) return i; return (-1); }

괜찮은! Python 버전보다 훨씬 더 복잡해 보이지 않으며 많은 작성이 필요하지 않습니다. 또한 문제를 해결하는 데 필요한 3개 어레이뿐만 아니라 모든 어레이에 대한 구현을 얻었습니다!

이 버전은 우리에게 꼭 필요한 것 같습니다. 정적 타이핑의 장점과 동적 타이핑의 장점 중 일부를 모두 얻습니다.

이것이 가능하다는 것은 좋은 일이지만, 더 좋을 수도 있습니다. 첫째, 일반화된 프로그래밍이 더 편리하고 아름다울 수 있습니다(예: Haskell 언어 사용). 둘째, 일반화된 프로그래밍 외에도 다형성(결과가 더 나쁠 수 있음), 함수 오버로딩(비슷한) 또는 매크로를 사용할 수도 있습니다.

역학의 정적

또한 많은 정적 언어가 동적 타이핑을 허용한다는 점도 언급해야 합니다. 예를 들면 다음과 같습니다.

  • C#은 동적 의사 유형을 지원합니다.
  • F#은 동적 유형 지정을 모방할 수 있는 ? 연산자 형식의 설탕 구문을 지원합니다.
  • Haskell - 동적 타이핑은 Data.Dynamic 모듈에서 제공됩니다.
  • Delphi - 특별한 Variant 유형을 통해.

또한 일부 동적 유형 지정 언어를 사용하면 정적 유형 지정을 활용할 수 있습니다.

  • Common Lisp - 유형 선언.
  • Perl - 버전 5.6 이후로는 상당히 제한적입니다.

강한 타이핑과 약한 타이핑

강력한 유형의 언어는 서로 다른 유형의 엔터티가 표현식에 혼합되는 것을 허용하지 않으며 자동 변환을 수행하지 않습니다. "강력한 형식의 언어"라고도 합니다. 이에 대한 영어 용어는 강한 타이핑입니다.

반대로 약한 유형의 언어는 프로그래머가 하나의 표현식에 다양한 유형을 혼합하도록 권장하며 컴파일러 자체는 모든 것을 단일 유형으로 줄입니다. "느슨한 형식의 언어"라고도 합니다. 이에 대한 영어 용어는 약한 타이핑입니다.

약한 타이핑은 종종 완전히 잘못된 동적 타이핑과 혼동됩니다. 동적 유형 언어는 약한 유형 또는 강력한 유형일 수 있습니다.

그러나 엄격한 타이핑을 중요시하는 사람은 거의 없습니다. 언어가 정적으로 입력되면 컴파일할 때 많은 잠재적인 오류를 발견할 수 있다고 흔히 말합니다. 그들은 당신에게 거짓말을 하고 있습니다!

언어에는 강력한 타이핑도 있어야 합니다. 실제로 컴파일러가 오류를 보고하는 대신 단순히 숫자에 문자열을 추가하거나 더 나쁜 경우 한 배열에서 다른 문자열을 빼면 유형의 모든 "검사"가 컴파일 시 수행된다는 것이 우리에게 무슨 소용이 있습니까? 단계? 맞습니다. 약한 정적 타이핑은 강력한 동적 타이핑보다 더 나쁩니다! (뭐, 그건 내 생각이다)

그렇다면 약한 타이핑에는 전혀 이점이 없습니까? 이렇게 보일 수도 있겠지만, 내가 강한 타이핑을 열렬히 지지한다는 사실에도 불구하고 약한 타이핑에도 장점이 있다는 점에는 동의할 수밖에 없습니다.

어떤 것을 알고 싶으십니까?

강력한 타이핑의 이점
  • 신뢰성 - 잘못된 동작 대신 예외 또는 컴파일 오류가 발생합니다.
  • 속도 - 꽤 비용이 많이 들 수 있는 숨겨진 변환 대신 강력한 타이핑을 사용하여 명시적으로 작성해야 하며, 이로 인해 프로그래머는 최소한 이 코드 조각이 느릴 수 있다는 것을 알 수 있습니다.
  • 프로그램 작동 방식 이해 - 다시 말하지만, 프로그래머는 암시적 유형 캐스팅 대신 모든 것을 직접 작성합니다. 즉, 문자열과 숫자를 비교하는 일은 마술이 아니라 저절로 발생하지 않는다는 것을 대략적으로 이해합니다.
  • 확실성 - 손으로 변환을 작성할 때 무엇을 변환하고 무엇으로 변환하는지 정확히 알 수 있습니다. 또한 이러한 변환으로 인해 정밀도가 떨어지고 잘못된 결과가 발생할 수 있다는 점도 항상 알고 있어야 합니다.
약한 타이핑의 이점
  • 혼합 표현식 사용의 편리성(예: 정수와 실수)
  • 타이핑을 추상화하고 작업에 집중합니다.
  • 항목의 간결함.

좋아요, 우리는 그것을 알아냈습니다. 약한 타이핑에도 장점이 있다는 것이 밝혀졌습니다! 약한 타이핑의 장점을 강한 타이핑으로 전환할 수 있는 방법이 있나요?

두 개도 있다는 것이 밝혀졌습니다.

명확한 상황에서 데이터 손실 없이 암시적 유형 캐스팅

와... 꽤 긴 말이군요. 이를 "제한된 암시적 변환"으로 더 단축하겠습니다. 그렇다면 명확한 상황과 데이터 손실은 무엇을 의미합니까?

모호하지 않은 상황은 본질이 즉각적으로 명확한 변형이나 작업입니다. 예를 들어 두 개의 숫자를 추가하는 것은 명확한 상황입니다. 그러나 숫자를 배열로 변환하는 것은 그렇지 않습니다. 아마도 한 요소의 배열이 생성될 것입니다. 아마도 이러한 길이의 배열은 기본적으로 요소로 채워지고 숫자는 문자열로 변환된 다음 배열로 변환될 것입니다. 문자).

데이터를 잃는 것이 훨씬 더 쉽습니다. 실수 3.5를 정수로 변환하면 데이터의 일부가 손실됩니다(사실 이 연산도 모호합니다. 반올림은 어떻게 수행됩니까? 위로? 아래로? 분수 부분을 버리나요?).

모호한 상황에서의 변환과 데이터 손실이 있는 변환은 매우 나쁩니다. 프로그래밍에서 이보다 더 나쁜 것은 없습니다.

내 말을 믿을 수 없다면 PL/I 언어를 공부하거나 사양을 찾아보세요. 모든 데이터 유형 간 변환에 대한 규칙이 있습니다! 이건 그냥 지옥이야!

좋아요, 제한된 암시적 변환에 대해 기억해 봅시다. 그런 언어도 있나요? 예, 예를 들어 Pascal에서는 정수를 실수로 변환할 수 있지만 그 반대는 불가능합니다. C#, Groovy 및 Common Lisp에도 유사한 메커니즘이 있습니다.

좋아, 나는 강력한 언어에서 약한 타이핑의 몇 가지 장점을 얻을 수 있는 방법이 아직 있다고 말했습니다. 그리고 그렇습니다. 그것은 존재하며 생성자 다형성이라고 불립니다.

훌륭한 하스켈 언어의 예를 들어 설명하겠습니다.

다형성 생성자는 숫자 리터럴을 사용할 때 안전한 암시적 변환이 가장 자주 필요하다는 관찰에서 탄생했습니다.

예를 들어, pi + 1 표현식에서 pi + 1.0 또는 pi + float(1) 을 쓰고 싶지 않을 것입니다. 나는 단지 pi + 1을 쓰고 싶습니다!

그리고 이것은 리터럴 1에 구체적인 유형이 없기 때문에 Haskell에서 수행됩니다. 그것은 전체도 아니고 실제도 아니며 복잡하지도 않습니다. 그것은 단지 숫자일 뿐입니다!

결과적으로 간단한 함수 sum x y 를 작성하고 x에서 y까지의 모든 숫자(1씩 증분)를 곱하면 한 번에 여러 버전을 얻게 됩니다. 정수의 합, 실수의 합, 유리수의 합, 복소수의 합 그리고 여러분이 직접 정의한 모든 숫자 유형의 합계도 계산할 수 있습니다.

물론 이 기술은 숫자 리터럴이 포함된 혼합 표현식을 사용할 때만 비용을 절감하며 이는 빙산의 일각에 불과합니다.

따라서 가장 좋은 해결책은 강한 타이핑과 약한 타이핑 사이의 경계에서 균형을 맞추는 것이라고 말할 수 있습니다. 하지만 아직 완벽한 균형을 이루는 언어는 없기 때문에 약한 유형의 언어(예: C, JavaScript, Lua, PHP)보다는 강력한 유형의 언어(예: Haskell, Java, C#, Python)에 더 의지합니다.

명시적 및 암시적 입력

명시적으로 유형이 지정된 언어에서는 프로그래머가 선언하는 모든 변수 및 함수의 유형을 지정해야 합니다. 이에 대한 영어 용어는 명시적 타이핑입니다.

반면에 암시적으로 유형이 지정된 언어는 유형을 잊어버리고 유형을 추론하는 작업을 컴파일러나 해석기에 맡기도록 권장합니다. 이에 대한 영어 용어는 암시적 타이핑입니다.

처음에는 암시적 유형 지정이 동적과 동일하고 명시적 유형 지정이 정적과 동일하다고 생각할 수 있지만 나중에는 그렇지 않다는 것을 알게 됩니다.

각 유형마다 장점이 있나요? 그리고 또 이들의 조합이 있나요? 두 가지 방법을 모두 지원하는 언어가 있나요?

명시적 입력의 이점
  • 각 함수에 서명(예: int add(int, int))이 있으면 함수가 수행하는 작업을 쉽게 확인할 수 있습니다.
  • 프로그래머는 특정 변수에 어떤 유형의 값을 저장할 수 있는지 즉시 기록하므로 이를 기억할 필요가 없습니다.
암시적 유형 지정의 이점
  • 단축 표기법 - def add(x, y) 는 int add(int x, int y) 보다 분명히 짧습니다.
  • 변화에 대한 저항. 예를 들어, 함수에서 임시 변수가 입력 인수와 동일한 유형인 경우 명시적으로 유형이 지정된 언어에서는 입력 인수의 유형을 변경할 때 임시 변수의 유형도 변경해야 합니다.

좋아요, 두 접근 방식 모두 장단점이 있다는 것은 분명합니다(누가 또 예상했겠습니까?). 따라서 이 두 접근 방식을 결합하는 방법을 찾아보겠습니다.

선택에 의한 명시적 입력

기본적으로 암시적 타이핑이 가능한 언어와 필요한 경우 값 유형을 지정할 수 있는 기능이 있습니다. 번역기는 실제 유형의 표현식을 자동으로 출력합니다. 이러한 언어 중 하나는 Haskell입니다. 명확성을 위해 간단한 예를 들어 보겠습니다.

명시적 유형 지정 없이 add (x, y) = x + y -- 명시적 유형 지정 add:: (Integer, Integer) -> Integer add (x, y) = x + y

참고: 저는 의도적으로 커링되지 않은 함수를 사용했으며 더 일반적인 add::(Num a) -> a -> a -> a 대신 의도적으로 개인 서명을 작성했습니다. 하스켈 구문을 설명하지 않고 아이디어를 보여주고 싶었습니다.

흠. 보시다시피 매우 훌륭하고 짧습니다. 함수를 작성하려면 공백을 포함하여 한 줄에 18자만 입력하면 됩니다!

그러나 자동 유형 추론은 상당히 복잡한 일이며 Haskell과 같은 멋진 언어에서도 때때로 실패합니다. (예는 단형성 제약 조건입니다)

기본적으로 명시적 타이핑이 있고 필요한 경우 암시적 타이핑이 있는 언어가 있나요? 범죄자
확신하는.

선택에 의한 암시적 입력

C++11(이전에는 C++0x라고 함)이라는 새로운 C++ 언어 표준에는 컴파일러가 컨텍스트를 기반으로 형식을 추론할 수 있도록 하는 auto 키워드가 도입되었습니다.

비교해 보겠습니다. // unsigned 유형을 수동으로 지정 int a = 5; 부호 없는 int b = a + 3; // unsigned int a = 5 유형의 자동 출력; 자동 b = a + 3;

나쁘지 않다. 하지만 기록은 크게 줄지 않았다. 반복자가 포함된 예를 살펴보겠습니다(이해하지 못하더라도 걱정하지 마세요. 가장 중요한 점은 자동 출력 덕분에 녹음이 크게 줄어든다는 것입니다).

// std::Vector 유형을 수동으로 지정 vec = 무작위벡터(30); for (std::Vector::const_iterator it = vec.cbegin(); ...) ( ... ) // 자동 유형 추론 auto vec = randomVector (서른); for (auto it = vec.cbegin(); ...) ( ... )

우와! 이것이 약어입니다. 좋아, 하지만 반환 유형이 인수 유형에 따라 달라지는 Haskell과 같은 작업을 수행하는 것이 가능합니까?

그리고 대답은 '예'입니다. auto와 결합된 decltype 키워드 덕분입니다.

// 수동 유형 int Divide(int x, int y) ( ... ) // 자동 유형 추론 auto Divide(int x, int y) -> decltype(x / y) ( ... )

이러한 형태의 표기법은 별로 좋아 보이지 않을 수 있지만 일반 프로그래밍(템플릿/제네릭)과 결합하면 암시적 유형 지정 또는 자동 유형 추론이 놀라운 효과를 발휘합니다.

이 분류에 따른 일부 프로그래밍 언어

나는 인기있는 언어의 작은 목록을 제공하고 "타이핑"의 각 범주로 어떻게 나뉘는지 쓸 것입니다.

JavaScript - 동적 / 약함 / 암시적 Ruby - 동적 / 강력 / 암시적 Python - 동적 / 강력 / 암시적 Java - 정적 / 강력 / 명시적 PHP - 동적 / 약 / 암시적 C - 정적 / 약 / 명시적 C++ - 정적 / 준강함 / 명시적 Perl - 동적 / 약함 / 암시적 Objective-C - 정적 / 약함 / 명시적 C# - 정적 / 강력 / 명시적 Haskell - 정적 / 강력 / 암시적 Common Lisp - 동적 / 강력 / 암시적

특히 CL, PHP 및 Obj-C에서 실수를 저질렀을 수도 있습니다. 일부 언어에 대해 다른 의견이 있으면 의견을 적어주세요.



질문이 있으신가요?

오타 신고

편집자에게 전송될 텍스트: