온라인 소프트웨어에서 임의의 주제를 읽는 동안 오리 타이핑 이라는 용어를 발견했으며 완전히 이해하지 못했습니다.
"오리 타이핑"이란 무엇입니까?
온라인 소프트웨어에서 임의의 주제를 읽는 동안 오리 타이핑 이라는 용어를 발견했으며 완전히 이해하지 못했습니다.
"오리 타이핑"이란 무엇입니까?
답변:
강력한 타이핑 이없는 동적 언어 에서 사용되는 용어 입니다.
아이디어는 객체에서 기존 메소드를 호출하기 위해 유형이 필요하지 않다는 것입니다. 메소드가 정의 된 경우이를 호출 할 수 있습니다.
그 이름은 "오리처럼 보이고 오리처럼, 거리면 오리입니다"라는 문구에서 유래합니다.
Wikipedia 에 훨씬 더 많은 정보가 있습니다.
덕 타이핑 은 오퍼레이션이 피연산자가 충족해야하는 요구 사항을 공식적으로 지정 하지 않고 제공된 것만으로 시도한다는 것을 의미 합니다 .
다른 사람들의 말과 달리, 이것은 반드시 동적 언어 나 상속 문제와 관련이있는 것은 아닙니다.
예제 작업 :Quack
객체에서 일부 메소드 를 호출하십시오 .
덕 타이핑을 사용 하지 않고이 f
작업을 수행 하는 함수 는 해당 인수가 일부 메서드를 지원해야한다고 미리 지정해야 Quack
합니다. 일반적인 방법은 인터페이스를 사용하는 것입니다
interface IQuack {
void Quack();
}
void f(IQuack x) {
x.Quack();
}
호출은 f(42)
실패하지만 f(donald)
만큼으로 작동 donald
의 인스턴스 IQuack
-subtype.
또 다른 접근 방식은 구조적 타이핑입니다 . 그러나이 방법 Quack()
은 미리 공식적으로 지정 quack
되어 있으므로 사전에 컴파일러 오류가 발생할 수 있습니다.
def f(x : { def Quack() : Unit }) = x.Quack()
우리는 심지어 쓸 수 있었다
f :: Quackable a => a -> IO ()
f = quack
Haskell에서 Quackable
typeclass는 메소드의 존재를 보장합니다.
내가 말했듯이, 오리 타이핑 시스템은 요구 사항을 지정하지 않고 작동하는 경우에만 시도합니다 .
따라서 파이썬의 다이내믹 타입 시스템은 항상 오리 타이핑을 사용합니다.
def f(x):
x.Quack()
경우 f
가져 x
을 지원하고 Quack()
, 런타임시 충돌합니다하지 않을 경우, 모든 것이 괜찮습니다.
그러나 오리 타이핑은 동적 타이핑을 의미하지는 않습니다. 실제로 요구 사항을 제공하지 않는 매우 인기가 있지만 완전히 정적 인 오리 타이핑 방식이 있습니다.
template <typename T>
void f(T x) { x.Quack(); }
이 기능은 일부 원하는 것을 어떤 방식으로 말하지 않는 x
그 캔을 Quack
너무 대신 그냥 시도, 컴파일시에 그것의 미세하고 모든 작업합니다.
def f(x)
대신에 def f(IQuack x)
.
질문의 의미론에 대한 토론은 상당히 미묘한 (그리고 매우 학문적이지만) 일반적인 아이디어는 다음과 같습니다.
오리 타이핑
(“오리처럼 걷고 오리처럼 If 거리면 오리입니다.”)- 그렇습니다! 그러나 그것은 무엇을 의미 하는가 ??! 이것은 예를 통해 가장 잘 설명됩니다.
오리 입력 기능의 예 :
마술 지팡이가 있다고 상상해보십시오. 특별한 힘이 있습니다. 지팡이를 흔들고 "드라이브!" 라고 말하면 그럼 차에 타요!
다른 것들에서도 작동합니까? 확실하지 않습니다 : 그래서 나는 트럭에서 그것을 시도하십시오. 와우-그것도 운전! 그런 다음 비행기, 기차 및 1 우즈에서 시도해보십시오 (사람들이 골프 공을 운전하는 데 사용하는 골프 클럽 유형입니다). 그들은 모두 운전한다!
그러나 그것은 찻잔이라고 할 수 있습니까? 오류 : KAAAA-BOOOOOOM! 그것은 잘 작동하지 않았다. ====> 찻잔은 운전할 수 없습니다 !! 어이!?
이것이 기본적으로 오리 타이핑의 개념입니다. 그것은 A의 시도 - 전에 - 당신 - 구매 시스템. 작동하면 모든 것이 잘됩니다. 그러나 수류탄이 손에 든 것처럼 실패하면 얼굴이 터질 것입니다.
다시 말해, 우리는 객체 가 아닌 객체가 무엇을 할 수 있는지에 관심 이 있습니다.
예 : 정적으로 입력 된 언어
객체가 실제로 무엇인지 에 대해 염려한다면 , 마술은 미리 설정된 승인 된 유형 (이 경우 자동차)에서만 작동하지만 트럭, 오토바이, 툭툭 등 운전할 수있는 다른 객체에서는 작동하지 않습니다 . 마술 지팡이가 자동차에서만 작동 하기를 기대하기 때문에 트럭에서는 작동하지 않습니다 .
다시 말해,이 시나리오에서 마술 지팡이는 물체 가 할 수있는 것 (예 : 자동차, 트럭 등을 운전할 수 있는지 )이 아니라 물체 가 무엇인지 (차입니까?)를 매우 면밀히 살펴 봅니다 .
트럭을 운전할 수있는 유일한 방법은 어쨌든 마술 지팡이가 트럭 과 자동차를 모두 예상 할 수있는 경우 (아마 "공통 인터페이스 구현")입니다. 그 의미를 모르는 경우 잠시 무시하십시오.
요약 : 주요 테이크 아웃
오리 타이핑에서 중요한 것은 객체 가 아닌 객체가 실제로 할 수 있는 것 입니다 .
간단한 함수를 디자인한다고 가정 해보십시오.이 함수는 유형의 객체를 가져 와서 메소드를 Bird
호출합니다 walk()
. 생각할 수있는 두 가지 접근 방식이 있습니다.
Bird
하거나 코드가 컴파일되지 않아야합니다. 누군가 내 기능을 사용하려면 Bird
s 만 수락한다는 것을 알고 있어야합니다.objects
객체의 walk()
메소드를 호출합니다 . 따라서 object
캔 walk()
이 올바른 경우 내 기능을 사용할 수 없으면 실패합니다. 따라서 여기에서 객체가 중요하지는 않습니다 Bird
. 이것이 중요합니다 walk()
(이것은 오리 타이핑입니다 )것을 고려되어야 오리 입력은 예를 들어 파이썬 용도, 어떤 경우에 유용 할 수 입력 오리 를 많이.
Wikipedia에 상당히 자세한 설명이 있습니다.
http://en.wikipedia.org/wiki/Duck_typing
덕 타이핑은 객체의 현재 메서드 및 속성 집합이 특정 클래스 또는 특정 인터페이스 구현에서 상속되지 않고 유효한 의미를 결정하는 동적 타이핑 스타일입니다.
중요한 점은 오리 타이핑을 사용하면 개발자가 실제 기본 유형이 아닌 소비되는 객체 부분에 더 관심이 있다는 것입니다.
오래된 관용구를 반복하는 많은 답변이 있습니다.
오리처럼 보이고 오리처럼 cks하면 오리
오리 타이핑으로 무엇을 할 수 있는지에 대한 설명이나 개념을 더 혼란스럽게 만드는 예를 들어보십시오.
그다지 도움이되지 않습니다.
이것은 내가 찾은 오리 타이핑에 대한 일반 영어 답변의 가장 좋은 시도입니다.
덕 타이핑 (Duck Typing)은 개체가 무엇을하는 것이 아니라 가능한 것으로 정의하는 것을 의미합니다.
즉, 객체의 클래스 / 유형에 대한 관심이 적고 어떤 메소드를 호출 할 수 있는지, 어떤 조작을 수행 할 수 있는지에 더 관심이 있습니다. 우리는 유형에 신경 쓰지 않고 할 수있는 일에 관심을 갖습니다 .
오리 타이핑 :
오리처럼 말하고 걷는다면 오리입니다
이것은 일반적이라고 납치 ( abductive 추론 또는라고도 retroduction , 내 생각을 명확하게 정의) :
에서 C (결론, 우리가 무엇을보고 ) 및 R (규칙, 우리가 알고있는 ), 우리는 결정 / 동의 / 가정 P (전제, 재산 즉 주어진 사실을)
... 의료 진단의 기초
오리 : C = 걷기, 대화 , R = 오리처럼 , P = 오리입니다
프로그래밍으로 돌아 가기 :
객체 o 는 메쏘드 / 프로퍼티 mp1을 가지며 인터페이스 / 타입 T 는 mp1을 요구 / 정의한다
객체 o 는 메소드 / 프로퍼티 mp2를 가지며 인터페이스 / 타입 T 는 mp2를 요구 / 정의한다
...
그래서, 더 간단하게 받아들이는 것보다 MP1을 오래가 몇 가지 정의를 충족하는 것처럼 모든 개체에 ... MP1을 단언와 ..., 컴파일러 / 런타임도 괜찮을 것 같네요 오는 타입입니다 T
그리고 위의 예와 같은 경우입니까? 오리 타이핑은 본질적으로 타이핑이 아닙니까? 아니면 암시 적 타이핑이라고해야합니까?
언어 자체를 보면 도움이 될 수 있습니다. 그것은 종종 나를 도와줍니다 (나는 영어 원어민이 아닙니다).
에서 duck typing
:
1) 단어 typing
는 키보드로 타이핑하는 것을 의미하지 않으며 (내 마음 속의 영속적 인 이미지처럼) " 그것이 어떤 종류의 것입니까? "
2) 단어 duck
는 그 결정이 어떻게 이루어 졌는지를 나타낸다. 다음과 같이 '느슨한'결정입니다. " 오리처럼 걷는다면 오리 입니다." 물건이 오리 일 수도 있고 아닐 수도 있기 때문에 '느슨한'것이지만 실제로 오리인지는 중요하지 않습니다. 중요한 것은 오리와 함께 할 수 있고 오리의 행동을 기대한다는 것입니다. 나는 빵 부스러기를 먹일 수 있고 물건은 나에게 가거나 나에게 청구하거나 물러날 수 있습니다 ...하지만 그리즐리처럼 나를 삼키지 않을 것입니다.
나는 일반적인 답변을 제공하지 않는다는 것을 알고 있습니다. 루비에서는 변수 나 메소드의 유형을 선언하지 않습니다. 모든 것이 일종의 객체 일뿐입니다. 규칙은 "유형이 아닌 클래스"입니다
루비에서 클래스는 결코 타입이 아닙니다. 대신, 객체의 유형은 해당 객체가 수행 할 수있는 작업에 의해 더 정의됩니다. 루비에서는 이것을 오리 입력이라고합니다. 물체가 오리처럼 걷거나 오리처럼 말하면 통역사는 그것을 오리처럼 취급합니다.
예를 들어, 노래 정보를 문자열에 추가하는 루틴을 작성 중일 수 있습니다. C # 또는 Java 배경에서 온 경우 다음을 작성하려고 할 수 있습니다.
def append_song(result, song)
# test we're given the right parameters
unless result.kind_of?(String)
fail TypeError.new("String expected") end
unless song.kind_of?(Song)
fail TypeError.new("Song expected")
end
result << song.title << " (" << song.artist << ")" end
result = ""
append_song(result, song) # => "I Got Rhythm (Gene Kelly)"
Ruby의 오리 타이핑을 받아들이면 훨씬 간단한 것을 작성할 수 있습니다.
def append_song(result, song)
result << song.title << " (" << song.artist << ")"
end
result = ""
append_song(result, song) # => "I Got Rhythm (Gene Kelly)"
인수 유형을 확인할 필요가 없습니다. 그들이 << (결과의 경우) 또는 제목과 아티스트 (노래의 경우)를 지원하면 모든 것이 작동합니다. 그렇지 않으면 어쨌든 메소드는 예외를 throw합니다 (유형을 확인했을 때와 마찬가지로). 그러나 확인하지 않으면 방법이 갑자기 훨씬 유연합니다. 배열, 문자열, 파일 또는 <<를 사용하여 추가하는 다른 객체를 전달하면 작동합니다.
오리 타이핑은 유형 힌트가 아닙니다!
기본적으로 "오리 타이핑"을 사용하기 위해 공통 인터페이스를 사용하여 특정 유형을 대상으로하지 않고보다 광범위한 하위 유형 (상속에 대해 이야기하지 않고 하위 유형을 의미 할 때 동일한 프로파일 내에 맞는 "사물"을 의미 함)을 대상으로합니다. .
정보를 저장하는 시스템을 상상할 수 있습니다. 정보를 쓰거나 읽으려면 일종의 스토리지와 정보가 필요합니다.
스토리지 유형은 파일, 데이터베이스, 세션 등일 수 있습니다.
인터페이스는 스토리지 유형에 관계없이 사용 가능한 옵션 (방법)을 알려줍니다. 이는 현재 구현 된 것이 없음을 의미합니다! 다시 말해서 인터페이스는 정보를 저장하는 방법에 대해 아무것도 모른다.
모든 스토리지 시스템은 인터페이스가 동일한 방법을 구현하여 인터페이스의 존재를 알아야합니다.
interface StorageInterface
{
public function write(string $key, array $value): bool;
public function read(string $key): array;
}
class File implements StorageInterface
{
public function read(string $key): array {
//reading from a file
}
public function write(string $key, array $value): bool {
//writing in a file implementation
}
}
class Session implements StorageInterface
{
public function read(string $key): array {
//reading from a session
}
public function write(string $key, array $value): bool {
//writing in a session implementation
}
}
class Storage implements StorageInterface
{
private $_storage = null;
function __construct(StorageInterface $storage) {
$this->_storage = $storage;
}
public function read(string $key): array {
return $this->_storage->read($key);
}
public function write(string $key, array $value): bool {
return ($this->_storage->write($key, $value)) ? true : false;
}
}
따라서 이제 정보를 쓰거나 읽을 때마다 :
$file = new Storage(new File());
$file->write('filename', ['information'] );
echo $file->read('filename');
$session = new Storage(new Session());
$session->write('filename', ['information'] );
echo $session->read('filename');
이 예제에서는 저장소 생성자에서 Duck Typing을 사용합니다.
function __construct(StorageInterface $storage) ...
그것이 도움이되기를 바랍니다.)
나는 유명한 문장을 내 방식으로 이해하려고 노력한다. "파이썬은 개체를 돌보지 않는 것이 실제 오리인지 아닌지이다. 개체는 첫 번째 '척', 두 번째는 '오리처럼'이다."
좋은 웹 사이트가 있습니다. http://www.voidspace.org.uk/python/articles/duck_typing.shtml#id14
필자는 오리 타이핑을 사용하면 자체 내부 데이터 구조를 가진 고유 한 클래스를 만들 수 있지만 일반적인 Python 구문을 사용하여 액세스 할 수 있다고 지적했습니다.