강한 <=> 약한 타이핑은 한 데이터 유형의 언어가 다른 데이터 유형에 대한 언어에 의해 자동으로 강요되는 양 또는 양에 대한 연속성뿐만 아니라 실제 값 이 얼마나 강하거나 약하게 입력 되는지에 관한 것 입니다. Python과 Java 및 대부분 C #에서 값의 유형은 스톤으로 설정됩니다. Perl에서는 그다지 많지 않습니다. 변수에 저장할 소수의 다른 값 유형이 실제로 있습니다.
사례를 하나씩 열어 봅시다.
파이썬
파이썬 예제 1 + "1"
에서+
연산자는 __add__
for 유형 int
을 호출하여 문자열 "1"
을 인수로 제공 하지만 NotImplemented가됩니다.
>>> (1).__add__('1')
NotImplemented
다음으로 통역사는 __radd__
str을 시도합니다 .
>>> '1'.__radd__(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__radd__'
실패하면 +
연산자는 결과와 함께 실패합니다 TypeError: unsupported operand type(s) for +: 'int' and 'str'
. 따라서 예외는 강력한 타이핑에 대해 많이 말하지 않지만 연산자 가 강제하지 않는다는 사실+
인수를 동일한 유형으로 자동으로 사실은 파이썬이 연속체에서 가장 약한 유형의 언어가 아니라는 사실에 대한 포인터입니다.
반면에 파이썬에서는 'a' * 5
이 구현됩니다.
>>> 'a' * 5
'aaaaa'
그건,
>>> 'a'.__mul__(5)
'aaaaa'
작업이 다르다는 사실은 약간의 타이핑이 필요합니다. *
곱하기 전에 값을 숫자 강제 변환하는 값을 약하게 입력 할 필요는 없습니다.
자바
Java 예제 String result = "1" + 1;
는 편의상 연산자 +
가 문자열에 과부하되어 있기 때문에 작동합니다 . 자바 +
연산자는을 만드는 순서를 대체 StringBuilder
합니다 ( 이 )
String result = a + b;
// becomes something like
String result = new StringBuilder().append(a).append(b).toString()
이것은 실제 강제 StringBuilder
가 없는 매우 정적 인 타이핑의 예입니다- append(Object)
여기에 특별히 사용되는 방법 이 있습니다. 설명서는 다음과 같이 말합니다.
Object
인수 의 문자열 표현을 추가합니다 .
전체적인 효과는 마치 인수가 메소드에 의해 문자열로 변환 된 것과 똑같이 String.valueOf(Object)
해당 문자열의 문자가이 문자 시퀀스에 추가 된 것과 같습니다.
어디 String.valueOf
다음
Object 인수의 문자열 표현을 리턴합니다. 인수가이면 null
문자열이 "null"
; 그렇지 않으면의 값 obj.toString()
이 반환됩니다.
따라서 이것은 언어에 의한 강요가 전혀없는 경우입니다-모든 관심사를 객체 자체에 위임하십시오.
씨#
Jon Skeet의 답변 에 따르면 연산자 +
는 string
클래스와 Java와 비슷하게 오버로드되지 않으며 정적 및 강력한 타이핑 덕분에 컴파일러가 생성하는 편의성입니다.
펄
perldata가 설명 하듯이
Perl에는 세 개의 기본 제공 데이터 유형 (스칼라, 스칼라 배열 및 "해시"라고하는 스칼라 배열)이 있습니다. 스칼라는 단일 문자열 (사용 가능한 메모리로만 제한되는 모든 크기), 숫자 또는 무언가에 대한 참조 (perlref에서 설명)입니다. 일반 배열은 0부터 시작하여 숫자로 색인화 된 스칼라 목록입니다. 해시는 연관된 문자열 키로 색인화 된 스칼라 값의 정렬되지 않은 콜렉션입니다.
그러나 Perl은 숫자, 부울, 문자열, null, undefined
s, 다른 객체에 대한 참조 등에 대한 별도의 데이터 유형을 가지고 있지 않습니다 . 0은 "0"만큼의 스칼라 값입니다. 문자열로 설정된 스칼라 변수 는 실제로 숫자로 변경 될 수 있으며 숫자 컨텍스트에서 액세스하는 경우 "문자열"과 다르게 동작합니다.. 스칼라는 Perl에서 무엇이든 가질 수 있으며 시스템에 존재하는만큼의 오브젝트입니다. 파이썬에서 이름은 단지 객체를 참조하고, Perl에서 이름의 스칼라 값은 변경 가능한 객체입니다. 또한 객체 지향 유형 시스템은이 위에 붙어 있습니다. 스칼라, 목록 및 해시에는 3 가지 데이터 유형이 있습니다. Perl의 사용자 정의 객체 대한 참조 (이전 3 개 중 하나에 대한 포인터)입니다.bless
패키지에 연결된 -이러한 값을 가져 와서 원하는 순간에 모든 클래스에 축복 할 수 있습니다.
펄은 심지어 값의 클래스를 변덕스럽게 바꿀 수 있습니다-파이썬에서 일부 클래스의 값을 생성하는 곳에서는 불가능합니다 object.__new__
. 파이썬에서는 생성 후 객체의 본질을 실제로 바꿀 수 없으며, Perl에서는 많은 것을 할 수 있습니다.
package Foo;
package Bar;
my $val = 42;
# $val is now a scalar value set from double
bless \$val, Foo;
# all references to $val now belong to class Foo
my $obj = \$val;
# now $obj refers to the SV stored in $val
# thus this prints: Foo=SCALAR(0x1c7d8c8)
print \$val, "\n";
# all references to $val now belong to class Bar
bless \$val, Bar;
# thus this prints Bar=SCALAR(0x1c7d8c8)
print \$val, "\n";
# we change the value stored in $val from number to a string
$val = 'abc';
# yet still the SV is blessed: Bar=SCALAR(0x1c7d8c8)
print \$val, "\n";
# and on the course, the $obj now refers to a "Bar" even though
# at the time of copying it did refer to a "Foo".
print $obj, "\n";
따라서 타입 아이덴티티는 변수에 약하게 묶여 있으며, 어떤 참조를 통해서든 변경 될 수 있습니다. 사실, 당신이 할 경우
my $another = $val;
\$another
\$val
여전히 축복받은 참조를 줄 지라도, 학급 정체성이 없습니다 .
TL; DR
자동 강제보다는 Perl에 대한 약한 타이핑에 대해 훨씬 더 많은 것이 있으며, 동적이지만 매우 강력한 유형의 언어 인 Python과 달리 값 자체의 유형은 돌로 설정되지 않습니다. 파이썬이 제공 TypeError
하는 1 + "1"
것은 Java 또는 C #에서 강력하게 유형이 지정되는 언어를 배제하지 않는 것처럼 유용한 무언가를 수행하는 것과 반대로 언어가 강력하게 유형화되었음을 나타냅니다.