Objective-C 메소드 이름의 마지막 부분이 인수를 가져와야하는 이유는 무엇입니까?
Objective-C에서는 마지막 구성 요소가 인수를받지 않는 방법 이름을 선언 할 수 없습니다. 예를 들어 다음은 불법입니다.
-(void)take:(id)theMoney andRun;
-(void)take:(id)yourMedicine andDontComplain;
Objective-C가 이런 방식으로 이유는 무엇입니까? 아무도 할 필요가 없다고 생각한 것이 스몰 토크의 유물이 아니 었습니까?
이 제한은 스몰 토크에서 의미가 있습니다. 스몰 토크에는 메시지 호출 주위에 구분 기호가 인수에 대한 최종 구성 요소는 마지막 항에 대한 메시지로 해석됩니다. 예를 들어 BillyAndBobby take:'$100' andRun
는 BillyAndBobby take:('$100' andRun)
. 대괄호가 필요한 Objective-C에서는 문제가 없습니다.
지원하는 변수 변수가 선택기 구성 요소는 메소드 이름으로, 언어가 측정되는 모든 일반적인 방법으로 우리를 선택할 수 없을 것입니다 프로그래머 픽 (예를보다 runWith:
보다는 take:andRun
)은 프로그램의 기능적 의미를 나 언어의 표현성에 영향을 주 언어로합니다. 실제로, 매개 변수가없는 구성 요소를 가진 프로그램은없는 구성 요소와 알파 동등합니다. 따라서 필요한 기능이 필요하지 않다는 답변에는 관심이 없습니다. 메소드가 필요하지 않도록 메소드 이름을 작성하는 방법. 가장 큰 이점은 가독성과 쓰기 능력입니다 (가독성과 사고합니다. 아시다시피). 자연어 문장과 훨씬 더 많은 방법 이름을 의미합니다. 좋아하는 것 (마 갤러거 가 "코코아와 사랑"에서 지적한 내용) 따라서 매개 변수를 적절한 명사 바로 옆 에 배치합니다 .-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
-(BOOL)application:(NSApplication*)theApplication shouldTerminateAfterLastWindowClosed
예를 들어 Apple의 Objective-C 작동은 종류의 선택기를 완벽하게 처리 할 수 있습니다. 컴파일러는 어떻습니까? 메소드 이름을 지원하지 않는 이유는 무엇입니까?
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Potrzebie : NSObject
-(void)take:(id)thing;
@end
@implementation Potrzebie
+(void)initialize {
SEL take_andRun = NSSelectorFromString(@"take:andRun");
IMP take_ = class_getMethodImplementation(self, @selector(take:));
if (take_) {
if (NO == class_addMethod(self, take_andRun, take_, "@@:@")) {
NSLog(@"Couldn't add selector '%@' to class %s.",
NSStringFromSelector(take_andRun),
class_getName(self));
}
} else {
NSLog(@"Couldn't find method 'take:'.");
}
}
-(void)take:(id)thing {
NSLog(@"-take: (actually %@) %@",NSStringFromSelector(_cmd), thing);
}
@end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Potrzebie *axolotl=[[Potrzebie alloc] init];
[axolotl take:@"paradichloroaminobenzaldehyde"];
[axolotl performSelector:NSSelectorFromString(@"take:andRun")
withObject:@"$100"];
[axolotl release];
[pool release];
return 0;
}
브래드 콕스입니다. 내 원래 대답은 질문을 오해했습니다. 나는 reallyFast가 아닌 구문 설탕이 아니라 더 빠른 메시징을 트리거하기 위해 코딩 된 확장이라고 생각했습니다. 진짜 대답은 스몰 토크가 그것을 지원하지 않았다는 것입니다. 아마도 그것의 파서가 (추정 된) 모호성을 다룰 수 없었습니다. OC의 대괄호가 모호함을 제거 할 것이지만, 저는 스몰 토크의 키워드 구조에서 벗어나는 것을 생각하지 않습니다.
21 년 동안 Objective-C를 프로그래밍하고 질문은 제 마음을 넘어선 적이 없습니다. 언어 디자인을 감안할 때 컴파일러는 옳고 작동 함수는 잘못 ().
메서드 이름이있는 인터리브 인수의 개념은 항상 인수가 하나 이상있는 경우 마지막 인수가 항상 메서드 호출 구문의 마지막 부분임을 의미합니다.
엄청나게 많이 생각하지 않고 현재 패턴을 적용하지 않는 구문상의 버그가있을 것입니다. 적어도 표현식과 인터리브 된 선택적 요소가있는 구문은 항상 구문 분석하기 가 더 어렵 기 때문에 컴파일러가 작성 하기가 더 어려워집니다. 평평한 가장자리가 그것을 막는 케이스가있을 수도 있습니다. 확실히 Obj-C ++는 더 어렵게 만들 것이지만 기본 구문이 이미 결정된 후 몇 년이 지나야 언어와 통합되지 않았습니다.
Objective-C가 이런 방식으로 설계된 이유에 관한 한, 대답은 언어의 원래 디자이너가 인터리브 구문이 마지막 인수를 넘어서는 것을 고려하지 않았다는 것입니다.
그것은 최선의 추측입니다. 나는 그들 중 한 명에게 물어보고 더 많은 것을 알게되면 대답을 업데이트 할 것입니다.
나는 브래드 콕스에게 이것에 대해 물었고 그는 자세하게 답변하는 데 매우 관대했습니다 (감사합니다, 브래드 !!) :
그 당시 저는 스몰 토크를 가능한 한 많이 C로 복제하고 가능한 한 효율적으로하는 데 집중했습니다. 여분의주기는 일반적인 메시징을 빠르게 만드는 데 사용되었습니다. 특별한 메시징 옵션 ( "reallyFast?"[ bbum : 예와 같이 'doSomething : withSomething : reallyFast'를 사용하여 물었습니다 ]) 에 대한 생각은 없었 습니다. 일반 메시지는 이미 가능한 한 빠르기 때문입니다. 여기에는 C proto-messager의 어셈블러 출력을 수동으로 조정하는 작업이 포함되었습니다.이 작업은 이식성 악몽이되어 일부는 나중에 제거되었습니다. 손으로 해킹 한 메시지가 매우 빠르다는 것을 기억합니다. 두 개의 함수 호출 비용에 대해; 하나는 메시지 로직에 들어가고 나머지는 거기에서 메소드 조회를 수행하기위한 것입니다.
정적 타이핑 향상은 나중에 Steve Naroff와 다른 사람들이 Smalltalk의 순수한 동적 타이핑에 추가되었습니다. 나는 그것에 제한적으로 관여했습니다.
브래드의 대답을 읽어보세요!
참고로 런타임은 실제로 선택자에 대해 신경 쓰지 않고 모든 C 문자열이 유효합니다. "== + === + ---__-- ¨¨¨¨와 같은 선택자를 만들 수 있습니다. ¨ ^ :::::: "인수가없는 경우 런타임은이를 허용합니다. 컴파일러는 허용하지 않거나 그렇지 않으면 구문 분석이 불가능합니다. 선택기에 관해서는 온 전성 검사가 전혀 없습니다.
Objective-C에서는 지원되지 않는다고 가정합니다. 스몰 토크에서도 사용할 수 없었기 때문입니다. 그러나 그것은 당신이 생각하는 것과는 다른 이유가 있습니다. 그들은 필요하지 않습니다. 필요한 것은 0, 1, 2, 3, ... 인수가있는 메서드에 대한 지원입니다. 모든 인수에 대해이를 호출하는 작업 구문이 이미 있습니다. 다른 구문을 추가하면 불필요한 혼란이 발생합니다.
여러 단어로 된 매개 변수가없는 선택기를 원했다면 왜 하나의 추가 단어로 중지할까요? 그런 다음 물어볼 수 있습니다
[axolotl perform selector: Y with object: Y]
또한 지원됩니다 (즉, 선택자는 단어 시퀀스이고 일부는 콜론과 매개 변수가 있고 다른 일부는 그렇지 않습니다). 이것이 가능했을지라도 아무도 그것을 가치 있다고 생각하지 않았다고 생각합니다.
'IT' 카테고리의 다른 글
"… 모듈이 아닌 것으로 해석되고 해석이 구성을 사용하여 수 없음"은 무엇을 의미합니까? (0) | 2020.09.07 |
---|---|
Eclipse에서 테스트하는 동안 -D 시스템 속성을 전달하는 방법은 무엇입니까? (0) | 2020.09.07 |
패치를 생성하여 폴더를 특정 커밋으로 되 돌리는 방법 (0) | 2020.09.07 |
getElementById에 대한 자바 펼쳐보기 약어 (0) | 2020.09.06 |
파일 이름 또는 확장명에 사용할 수있는 DateTime.ToString () 형식? (0) | 2020.09.06 |