【问题标题】:Can't figure out this dynamic typing thing无法弄清楚这个动态打字的东西
【发布时间】:2011-10-05 16:17:41
【问题描述】:

我正在整理一份面试问题列表,供面试 Cocoa 开发人员的人参考。我是一名程序员,但我从未做过 Objective-C。我偶然发现了一个涉及动态类型的interesting question。它应该是初级的,我已经尝试过并编译过它,但我仍然不确定它是如何以及为什么工作的。

问题是

当您执行以下操作时,在编译时和运行时会发生什么:

NSString *s = [NSNumber numberWithInt:3];
int i = [s intValue];

在调试器中我得到

i = (int) 3 s = (__NSFCNumber*) 0x383(无效地址)

NSLog(@"%d",i) 的输出为3NSLog(@"%@",s) 的输出为3

有人能解释一下编译器和运行时系统是如何处理这一切的吗科学?

【问题讨论】:

    标签: objective-c cocoa dynamic-typing


    【解决方案1】:

    你的 s 只是一个标准的 C 指针,分配了一个 NSNumber 对象(指向 a 的指针)。

    NSNumberNSString 回复 intValue。就是这样。

    【讨论】:

    • 关于面试的旁白:任何优秀的程序员都可以学习任何语言,所以我更感兴趣的是了解面试者的能力而不是他们的知识。我讨厌测试类型的问题 - 尽管您链接中的问题大多是对话的良好开端。
    • 你的最后一句话是我所缺少的。我没有意识到这两种类型都会回复intValue
    • 关于面试问题,我完全同意。我通常不会通过给他们测试类型的问题来采访他们,但我们正在寻找一位 iPhone 开发人员,而且公司里没有人对 iPhone 编程了解多少,所以我只是想看看他们在概念。这就是为什么我采用标准化的问答式面试的原因,但感谢您的建议。你的观点很有道理。
    【解决方案2】:

    s 是一个您已声明将指向NSString 对象的指针。它可以指向任何东西,但理想情况下它应该指向一个 NSString。然而,代码示例有 s 指向一个 NSNumber 对象。

    只要您只向s 发送那些NSNumber 响应的方法就可以了(编译器警告除外)。如果你试图向s 指向的那个对象发送一个 NSString 方法,那么 NSNumber 没有响应你会得到一个异常。如果对象具有匹配的选择器签名(即:@selector(intValue)),则将调用该方法。

    【讨论】:

    • 不太正确,因为 intValue 实际上是 NSString 上的一个方法。最好说 NSNumber 和 NSString 都响应 intValue 的签名(或@selector 值)。
    【解决方案3】:

    为变量“s”声明 NSString 仅仅是为了帮助编译器解释变量“s”的意图。它允许编译器在您打算使用某种类型的变量但意外分配了不同类型的变量的情况下强制执行静态类型检查。在 ObjC 中,变量可以指向任何对象,而括号语法是向对象发送“消息”的一种方式。发送消息指示编译器生成查找实现消息的函数的代码。在 ObjectiveC 中,消息也被称为选择器。 (低层次的细节稍微多一些,但在高层次上就是这样。)这是动态类型的动态部分,也称为“鸭子打字”。这个想法是,如果它看起来像一只鸭子,你应该能够让它像鸭子一样嘎嘎叫。本质上,任何遵循特定形状的对象都可以分配给适合该形状的类型。

    考虑以下几点:

    Dog *myPuppy = [[Cat alloc] init] autorelease];
    [myPuppy walk];
    Food *preparedDish = [self prepareMealForPet];
    [myPuppy eat: preparedDish];
    

    编译器会在此处标记您,表明您打算花时间与狗相处,但实际上是在与猫打交道。然而,这是完全有效的,因为猫的形状类似于狗,因为它们都可以走路和吃准备好的饭菜。 Duck typing 可以让您摆脱这种情况,因为在很多情况下您需要接受事先不知道的变量类型。此外,通过自省,您可以在运行时发现对象的形状。如果我们想让我们的小狗吠叫,请考虑上面的代码。我们会得到一个异常,应用程序会崩溃。但是,我们可以使用自省来询问我们的对象是否响应“吠叫”消息以避免崩溃。

    if([myPuppy respondsToSelector:@selector(bark)]) {
       [myPuppy bark];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多