변수에 유형이 필요한 이유는 무엇입니까?


10

그래서 우리는 다음과 같이 씁니다.

Customer c = new Customer();

디자인이 우리가 쓰는 것과 다른 이유는 무엇입니까?

c = new Customer();
c.CreditLimit = 1000;

컴파일러는 고객에게 c 포인트를 계산하고 고객 멤버가 c에서 호출되도록 할 수 있습니까?

나는 우리가 쓰고 싶을 수도 있다는 것을 안다.

IPerson c = new Customer();
IPerson e = new Employee();

쓸 수 있도록 :

public string GetName(IPerson object)
{
    return object.Name
}

string name = GetName(c); // or GetName(e);

그러나 우리가 쓴다면 :

c = new Customer();
e = new Employee();

우리는 여전히 쓸 수 있습니다 :

public string GetName(object)
{
    return object.Name
}    

string name = GetName(c); // or GetName(e);

객체 c 참조의 유형이 Name 속성을 지원하지 않는 경우 (메서드 내의 인수 / 매개 변수에 어떤 멤버가 사용되는지 확인할 수있는 경우) 컴파일러가 바로 위에있는 코드에 대해 불평하거나 런타임이 불평 할 수 있습니다.

C #의 동적 키워드를 사용하더라도 여전히 변수 'type'(런타임에 결정됨)을 사용하고 있습니다. 그러나 왜 변수에 타입이 필요한가? 나는 타당한 이유가 있어야한다고 생각하지만 그것을 생각할 수는 없습니다!


12
그렇기 때문에 Python 및 Ruby (및 기타)와 같은 동적 언어가 있습니다. 이 질문에 대한 답변 이 없습니다 . 일부 언어는 유형 선언을 사용하고 일부 언어는 사용하지 않습니다.
S.Lott

2
"해당 언어의 변수에는 유형이 전혀 없습니까?" 옳은. 변수 는 파이썬에서 타입이 없습니다. 객체에는 유형이 있으며 변수는 단순히 객체에 대한 참조입니다. 귀하의 질문 은 실제로 관찰입니다. 특히 "모든 언어에 변수 선언이 필요한 것은 아닙니다". 답이 없습니다. 따라서 건설적이지 않아 폐쇄 될 가능성이 큽니다.
S.Lott

1
형식 선언없이 변수를 선언 할 수 있지만 형식 유추 를 사용하여 형식 을 알아낼 수 있도록 Boo를 살펴보고 싶을 수 있습니다. 따라서 강력한 타이핑의 정확성과 성능 이점을 희생하지 않습니다.
메이슨 휠러

2
var x = 1; -32 비트, 64 비트, 16 비트 숫자를 의미 했습니까? 바이트? 흙손? 더블? 소수? 이것은 단지 프리미티브를 다루고 있습니다.
직업

4
varC #에서 사용할 수 있으며 변수를 선언하려는 위치가 항상 좋을 수 있습니다.
다니엘 리틀

답변:


22

그러나 왜 변수에 타입이 필요한가?

  1. 잘못된 형식의식이 변수에 할당 된 버그를 발견 할 수 있습니다. 일부 언어에는 다이나믹 한 타이핑 기능 이있어 원하는 유형의 유연성에 대해 변수 당 유형의 정확성을 보장합니다.
  2. 형식을 사용하면 컴파일러가보다 효율적인 코드를 생성 할 수 있습니다. 동적 타이핑은 런타임에 유형 검사를 수행해야 함을 의미합니다.

1
공감 비를 설명하십시오.
Fred Foo 2019

4
또한 런타임 동안 유형 정보를 확인해야하기 때문에 동적 입력은 성능 비용이 발생합니다.
Charles Salvia

@CharlesSalvia : 좋은 지적은 대답에 추가했습니다.
Fred Foo 2019

2
@ sturdytree : "유형이 없으면 잘못 입력 할 수 없습니다"라는 언어 규칙에 따라 사실입니다. 그러나 시맨틱 관점 에서 변수에 여전히 잘못된 유형이 지정 될 수 있습니다. 예를 들어 생성자 이름을 잘못 입력하고 프로그램이 계속 실행되지만 원하는 작업을 수행하지 않습니다.
Fred Foo 2012

5
@sturdytree 타입 검사에 실제로 타입이 없는 변수 가있는 언어는 없지만 , 형식 유추 가있는 언어가 있습니다 . 다시 말해서, 언어는 변수의 사용법을보고 사용에서 유형을 추론합니다. 충돌이있는 경우 (예 : a = new Bar()class에서 메소드 를 수행 한 후 나중에 호출 Baz) 컴파일러에서 오류가 발생합니다. Haskell 및 OCaml과 같은 언어는 형식 유추를 개척했지만 C #에는 var키워드 와 함께 존재 합니다.
Quancle

9

변수의 유형을 추적하지 않는 언어가 존재하며이를 "동적 유형"이라고하는 완벽한 유효 지점이 있습니다. 이 카테고리에는 JavaScript, Perl, Lisp 및 Python과 같은 언어가 포함됩니다.

정적으로 형식화 된 언어에서 얻을 수있는 이점은 컴파일 타임 오류 검사가 몇 가지 더 있다는 것입니다.

예를 들어 다음과 같은 방법이 있다고 가정하십시오.

public addCustomerContact(Customer client, Employee contact) {
   ...
} 

코드에 고객 bob과 직원 이있는 경우 james실수로을 (를) 잘못 호출 addCustomerContact(james, bob)할 수 있습니다. 그러나 컴파일러가 변수의 유형을 모르는 경우, 잘못된 호출을했다는 경고를 표시 할 수 없습니다. 대신 런타임시 오류가 발생합니다. 동적으로 유형이 지정된 언어는 메소드에 전달 된 매개 변수 유형의 경우 코드에서 james오브젝트 의 고객 전용 특성 또는 오브젝트의 직원 전용 특성을 사용하려고 시도 할 때마다이 문제점이 발생 bob합니다. 쌍 (james, bob)이 고객 연락처 목록에 추가 된 후 시간이 오래 걸릴 수 있습니다.

이제 왜 컴파일러가 여전히 jamesand 의 유형을 유추하여 bob여전히 경고 할 수 없는지 궁금 할 것입니다. 때로는 가능할 수도 있지만 변수에 실제로 유형이없는 경우 다음을 수행 할 수 있습니다.

var james;
var bob;
if (getRandomNumber() > 0.5) {
   james = new Customer();
   bob = new Employee();
} else {
   james = new Employee();
   bob = new Customer();
}

변수에 유형이 없다고 말했기 때문에 모든 변수에 값을 할당하는 것이 합법적입니다. 또한 변수의 유형을 알 수 없다는 것을 의미합니다. 실행 경로에 따라 유형이 다를 수 있기 때문입니다.

일반적으로 컴파일 단계가없는 스크립트 언어에는 동적으로 유형이 지정된 언어가 사용되므로 컴파일 오류가 없으므로 변수 유형을 제공하는 데 필요한 추가 키 입력이 그다지 유용하지 않습니다.

동일한 디자인을 구현하는 데 필요한 코드가 적다는 점에서 동적으로 유형이 지정된 언어에도 몇 가지 뚜렷한 이점이 있습니다. 모든 것이 "오리 유형이 지정되어"있기 때문에 인터페이스를 작성할 필요가 없습니다. , 객체가 속한 클래스가 아니라) 변수에 명시 적 유형을 부여 할 필요는 없습니다. 코드 실행을 시작하기 전에 버그가 다소 줄어든다는 점에서 트레이드 오프가 있습니다.


시어 도어 감사합니다. "하지만 컴파일러가 변수 유형을 모르는 경우 잘못된 호출을했다는 경고를 표시 할 수 없습니다."언급했듯이 컴파일러는 변수가 가리키는 객체의 유형을 알 수 있습니다.
sturdytree

Theodore : 여러분의 예제 인 james / bob에서, 우리는 프로그래머로서 우리가 변수를 어떻게 사용하고 (네이밍이 도움이되는지) 알고 있어야하므로 문제가 없습니다. "우리는 항상 변수의 타입을 알 수 없다"고 말할 때 변수가 가리키는 객체의 타입을 항상 알 수는 없지만 컴파일러는 이것을 해결할 수 있으므로 잘못된 멤버에 대해 경고 할 수 있다고 가정합니다. 적용됩니다 (즉, 정적 검사를 할 수 있음).
sturdytree

2
위의 예제를 사용하면 객체의 유형을 정적으로 알 수 없습니다 ... 실행 경로에 따라 유형 정보가없는 변수에 저장된 객체의 유형이 다를 수 있습니다. 컴파일 타임 유형 정보를 유추 할 수있는 C #과 같은 언어를 사용할 수 있지만, 아는 한 정적 유형 검사 및 유형이없는 변수가 모두있는 언어는 없으며 정적 분석의 계산 복잡도 큰.
Theodore Murdock

Theodore, 고마워, 당신은 내가 말하고있는 것이 정적 유형 검사 (객체 유형에 따라)와 유형이없는 변수가있는 언어라는 것을 올바르게 이해했습니다. 안타깝게도 안타깝습니다. 파이썬에는 유형이없는 변수가 있지만 정적 유형 검사가없는 것처럼 들립니다.
sturdytree

1
-1; 강력 / 약한 타이핑은 정적 / 동적 타이핑과 직교합니다. C는 정적으로 약한 유형입니다. Lisp와 Python은 모두 동적으로 강력하게 형식화됩니다.
Fred Foo

5

따라서 전문 프로그래머는 여부를 알아낼 필요가 없습니다

10 + "10"

is "1010" or 20....

정적 형식 언어의 컴파일 타임 또는 동적 형식 언어의 런타임에서 오류는 무엇입니까? 어쨌든 제정신입니다.


2
즉, Perl은 제정신이 아닌가? :)
Fred Foo 2013

5
@larsmans : 사실, 아닙니다. 그러나 그것은 순수한 의견입니다.
NotMe

2
@ChrisLively : 이제 사실 문제가 다행입니다. 내 Perl을 사랑하는 동료들을 설득하기 위해 언제든지 내 직장으로 오십시오;)
Fred Foo

2
10 + "10"은 정수 유형의 오브젝트와 문자열 유형의 오브젝트에 '+'연산자를 사용하고 있습니다. 컴파일러에서 오류가 발생했습니다. 내 질문은 객체가 아닌 변수 유형과 관련이 있습니다.
sturdytree 2013

2
그것은 이다 유효한 C : 그것의 포인터 연산.
dan04

4

변수가 one(1로 설정되어 있고) 평가를 시도 했다고 가정합니다 one + one. 유형에 대해 모른다면 1 + 1이 모호합니다. 2 또는 11이 정답 일 수 있다고 주장 할 수 있습니다. 문맥이 주어지지 않으면 모호해진다.

SQLite에서 데이터베이스 유형이 실수로 VARCHAR대신 대신 설정되고 INT작업이 완료되었을 때 사람들이 예기치 않은 결과를 얻었습니다.

c #에서 컨텍스트가 유형을 유추하는 경우 var키워드를 사용할 수 있습니다 .

var c = new Customer();
var e = new Employer();

컴파일 타임에 유추 된 유형으로 c와 e를 컴파일합니다.


1
파이썬에서는 1 + 1항상 유형 int이 있지만이를 선언 할 필요는 없습니다. 문제는 변수 이 아닌 유형을 갖는 이유에 관한 것 입니다.
Fred Foo 2019

내 예에서 사용 variables하지 않았을 values때 보지 못해서 죄송합니다 1 + 1. 나는 그것이 명확하지 않은 것 같아요.
Stephen Quan

여전히 동적으로 유형이 지정된 언어가이를 처리 할 수 ​​있습니다. Python에서는을 one=1; print(one+one)인쇄합니다 2. one="1"; print(one+one)인쇄합니다 11. SQLite 예제는 더 설득력이 있지만 타이핑이 약한 문제는 실제로 C #과 관련이 없습니다.
Fred Foo

내 제안 체계에서 1 = 1은 정수 유형을 가리키는 변수를 의미합니다 (유형은 전혀 제안하지 않습니다-객체에는 유형이 있음). 하나 + 하나는
모호

1
안녕하세요 @ dan04, 나는 ORDER BY실수로 VARCHAR필드에서 수행 보았다 . stackoverflow.com/questions/9103313/…을 참조하십시오 .
Stephen Quan

4

변수는 연관된 유형을 가질 필요는 없습니다. 이것이 사실 인 언어로는 Lisp, Scheme, Erlang, Prolog, Smalltalk, Perl, Python, Ruby 등이 있습니다.

변수가 타입 을 가질 수도 있지만 프로그램에서 타입 을 필요는 없습니다 . 이를 일반적으로 형식 유추라고합니다. ML, Haskell 및 해당 하위 항목에는 강력한 형식 유추가 있습니다. 일부 다른 언어는 C ++ auto선언 과 같이 더 적은 형태로 사용 합니다.

형식 유추에 대한 주요 주장은 가독성을 손상 시킨다는 것입니다. 일반적으로 유형을 기록 할 때 코드를 이해하는 것이 더 쉽습니다.


1

변수가 나타내는 유형을 식별하면 몇 가지 사항에 대해 설명합니다. 변수의 메모리 할당 요구 사항을 식별하고 변수의 호환성 및 범위 규칙을 정의하고 있습니다. 저장하는 데이터의 의도에 대한 혼동을 피하고 컴파일 타임에 코드의 잠재적 인 문제를 식별 할 수있는 비교적 저렴한 수단을 제공합니다.

다음 변수를 선언 한 경우 :

myVar      = 5;
myOtherVar = "C";

이러한 변수에 대해 무엇을 추론 할 수 있습니까? 되어 myVar부호있는 또는 부호? 8 비트, 64 비트 또는 그 사이에 있습니까? 가 myOtherVar문자열 (효과적으로 배열) 또는 숯불은? ANSI 또는 유니 코드입니까?

특정 데이터 유형을 제공함으로써 응용 프로그램의 메모리 요구 사항을 최적화하는 방법에 대한 힌트를 컴파일러에 제공합니다. 일부 언어는 이런 종류의 일을 많이 신경 쓰지 않으므로 런타임에 이러한 문제를 처리 할 수 ​​있으며 다른 언어는 코드를 분석하여 데이터 유형을 유추 할 수 있기 때문에 일정량의 동적 입력을 허용합니다.

강력한 형식의 언어를 사용하는 또 다른 요점은 변수를 사용할 때마다 컴파일러에 명령을 제공 할 필요가 없다는 것입니다. 변수에 액세스 할 때마다 컴파일러에게 변수의 값 유형을 알려주기 위해 효과적으로 캐스트해야한다면 코드가 얼마나 끔찍하고 읽을 수 없을지 상상할 수 있습니까? !!


좋은 점은 컴파일러가 값을 기반으로 가장 효율적인 유형 (예 : small int)을 사용할 수 있지만 특정 작업을 수행 할 수 있도록 "C"가 char이 아닌 문자열 객체가되기를 원할 수 있습니다. . 그러나 이런 경우에는 = (문자열) "C"만 지정할 수 있습니다. 이것은 문자열 객체를 만들고 'a'(유형이 지정되지 않은 변수) 만 가리 킵니다. 문자열 a = "C"보다 더 끔찍한 것으로 보지 않습니다.
sturdytree

0

컴퓨터 프로그램은 언어 런타임 (대부분의 경우 툴킷으로 확장)으로 표시되는 "기계"가 어떤 순서로 또는 어떤 조건에서 수행해야하는지 설명하는 프로세스 노드의 그래프입니다. 이 그래프는 특정 언어로 작성된 텍스트 파일 (또는 여러 개의 텍스트 파일)로 표시되며 컴파일러 / 통역사가이 파일을 읽거나 (역 직렬화) 만들 때 (부분 또는 전체) 생성됩니다. 또한 실제로이 그래프를 작성하고 대상 언어로 소스 코드를 생성 할 수있는 일부 환경 (UML 또는 그래픽 프로그램 생성 도구)이 있습니다.

내가 왜 이것을 말합니까? 이것은 귀하의 질문에 대한 답변으로 이어지기 때문입니다.

프로그램 텍스트는 프로세스 단계 (조건, 조치) 및 구조 (솔루션에서 어떤 구성 요소를 사용하는지)를 포함하여 컴퓨터가 실제 작업을 해결하는 방법에 대한 지시 사항입니다. 후자는 다른 구성 요소의 인스턴스를 가져 오거나 생성하여 명명 된 상자 (변수)에 넣고 사용합니다. 데이터 및 서비스에 액세스합니다.

일부 언어는 레이블 만 중요한 균일 한 상자를 제공하지만 그 안에는 아무 것도 넣을 수 없으며 "target"이라는 변수를 사용하여 처음에 "Person"을 저장하고 끝에 "Car"를 저장할 수도 있습니다 같은 알고리즘. 다른 사람은 "모양의"상자를 만들어야하므로 사람이나 자동차에 대해 다른 상자를 만들어야합니다. "일반 상자"(Java Object, C / C ++ void *, Objective C "id"...)를 만들 수는 있지만 원하는대로 캐스팅하십시오. 유형이 지정된 언어를 사용하면 변수에 대한 "유형 계약"을 작성하여 구조를보다 자세하게 표현할 수 있습니다 (이 한계를 해킹 할 수는 있지만) 유형이 지정되지 않은 언어는 "이번 상자에 넣은 내용을 확실히 알고 있습니다" 기본 및 유일한 동작으로.

두 가지 접근법 모두 실행 가능하며 컴파일러 인텔리전스, 많은 프로그래밍 서적, 사례 및 프레임 워크를 사용하여 작성된 다양한 프레임 워크 및 다른 프레임 워크에 대한 다른 서적을 보유하고 있습니다. 따라서 오늘날 대답은 유형의 사용 여부에 대한 적절하게 설립, 측정 및 확인 된 진술보다 취향과 실제 프로그래머 팀의 지식에 관한 것 같습니다.

나는 특히 장기적인 대규모 팀 (일명 "심각한") 프로젝트를 위해 트릭보다 규칙을 선호한다고 말할 필요는 없다고 생각한다. 이유 : 내가 아는 한, SW 프로젝트 실패 / 슬립의 가장 큰 원인은 불명확 한 요구 사항과 불충분 한 디자인 (알고있는 연구에 따르면 80 %!)이며 실제 코딩에는 몇 퍼센트 만이 남아 있습니다. 모든 규칙과 계약은보다 깔끔한 디자인과 미래를 생각하며, 적절한 사람들이 조기에 결정을 내려야합니다. 유형은 규칙을 의미합니다. 덜 "자유"와 "차가움"– 더 많은 준비, 사고, 코딩 표준, 통제 된 팀워크. 나에게 이것은 성공의 필수 요소와 "집, 스위트 홈"처럼 들린다.

내 2 센트


-3

동적 입력을 사용하는 AFIAK의 모든 언어는 해석 된 언어입니다. 그것은 이미 매우 비효율적이며 동적 타이핑의 비 효율성을 추가하면 시간을 크게 잃지 않을 것입니다. 그러나 컴파일 된 언어는 실제로 실행될 때 이름으로 사물을 언급하지 않습니다. (언제나 .net 리플렉션 등의 사용을 금지합니다. 기본 언어에 비해 속도가 매우 느린 기능입니다.) 모든 이름을 검색하는 것은 느리고 느리고 느릴 것입니다.


3
당신은 잘못 알고 있습니다. 동적 형식 언어를위한 많은 컴파일러가 있으며 그 중 일부는 매우 빠릅니다. 예로는 Common Lisp, Scheme 및 Erlang이 있습니다.
Ryan Culpepper

3
"통역 된 언어"와 같은 것은 없습니다. 언어는 추상적 인 수학 규칙 세트입니다. 언어는 컴파일되거나 해석되지 않습니다. 언어는 단지 컴파일과 해석은 언어가 아닌 구현의 특성입니다. 모든 언어는 인터프리터로 구현할 수 있으며 모든 언어는 컴파일러로 구현할 수 있습니다. 그리고 거의 모든 언어에는 해석 및 컴파일 구현이 있습니다. 예를 들어 C에 대한 해석기와 ECMAScript, Ruby 및 Python에 대한 컴파일러가 있습니다.
Jörg W Mittag

-4

동적 타입 언어는 종종 "객체 지향"으로 선전됩니다. 그들은 아닙니다. 그것들은 캡슐화 지향적이지만 결코 객체 지향적 일 수는 없습니다. 객체 방향은 모든 유형에 관한 것입니다.

"소년의 자전거를 식료품 점에 타서 식료품 점에서 빵 한 덩어리를 구입합니다." 객체 지향을 사용하면이 실제 시나리오를 설명하는 클래스 (유형) 세트를 즉시 작성할 수 있습니다.

동적 형식 언어에서는 시나리오를 다음과 같이 표현할 수 있습니다.

"객체는 객체의 객체를 객체로 타고 객체에서 객체를 구입합니다."

객체 지향의 힘은 세상을 자연적으로 모델링 할 수있는 능력에있어서 소프트웨어 개발자는 두뇌의 양쪽을 사용하여 소프트웨어를 작성하고 컴퓨터 프로그래머가 아닌 인간으로서 더 많은 문제를 해결할 수 있습니다. 동적으로 입력 된 언어에는이 기능이 없습니다.

정적 타이핑은 통합 개발 환경이 변수 유형을 알고 있기 때문에 코딩 효율성, 재사용 성 및 유지 관리 성이 향상됩니다. 변수 유형을 알고 있으면 IDE에서 자동 완성 기능을 제공하여 멤버 속성의 철자가 "backlightControl"인지 "backLightControl"또는 "bkLightCtrl"인지 기억하기 위해 프로그래머가 클래스 정의를 다시 참조 할 필요가 없도록 할 수 있습니다.

IDE는 변수가 리팩토링되는 객체의 인스턴스를 보유하는 모든 위치를 알고 있기 때문에 정적 타이핑은 자동 리팩토링을 허용합니다.

정적 타이핑은 재사용 성과 유지 보수성을 향상시킵니다. 일회용 코드에는 동적 입력이 더 좋습니다. 새로운 개발자가 거리에서 나와 기존 코드를 살펴 보자. 코드가 정적으로 유형이 지정되면 개발자는 두 번의 마우스 클릭으로 관련된 각 변수의 클래스 정의를 검사하고 클래스가 무엇인지 알고 사용 가능한 다른 메소드와 특성을 알 수 있습니다. 코드가 동적으로 입력되면 개발자는 전역 검색을 사용하여 진행 상황을 파악해야합니다.


2
나는 당신의 주장의 첫 부분에서 당신과 동의하지 않는 것이 두렵습니다. 동적 유형 언어는 일반적으로 "객체 지향"이지만 "클래스 지향"은 아닙니다. 이것은 중요한 차이점입니다. 예를 들어, 실제로 환상에 살고 있습니다. 당신은 할 수 있습니다 Boy클래스를,하지만 난 그것을 모두에게 "소년"수행하는 실제 작업을 수행 할 수 있습니다 의심한다. 그러나 동적 예 (개체 타기 ...)에, 우리는이 "소년"개체에 대한 유일한 중요한 일을 알고있다 - 그것은 수 타고 . 이것이 동적 유형 언어의 기본 철학입니다. + ve 및 -ve가 있습니다. 당신이 좋아하는 것은 당신의 의견입니다.
Chip
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.