objective-c - 为什么Objective-C类和协议(protocol)可以重名,而Swift不可以,语言实现有什么区别?

标签 objective-c swift

Swift,无法编译,编译器会直接报错。

protocol Test {}

struct Test {}


// Swift compile output:

// Untitled.swift:4:8: error: invalid redeclaration of 'Test' struct Test {}

// Untitled.swift:2:10: note: 'Test' previously declared here protocol Test {}

Objective-C,可以编译成功,比如NSObject是类名,也是协议(protocol)名

#import <Foundation/Foundation.h>

@protocol Test
@end

@interface Test
@end

int main(int argc, char *argv[]) {
    @autoreleasepool {
        NSLog(@"Hello word");
    }
}
// Objective-C output
// 2018-03-11 23:14:20.341 Untitled[34921:1272761] Hello word

最佳答案

Objective-C 和 Swift 具有不同的名称解析方案,这导致了这种情况的发生。

  1. 在 Objective-C 中,类名和协议(protocol)名通常是唯一的。 (您始终可以注册一个与现有协议(protocol)或类同名的新协议(protocol)或类,但您通常会收到警告,并且事情肯定会表现得很奇怪。)但是,类名和协议(protocol)名存在于不同的 namespace 中——类名可以隐藏协议(protocol)名称,反之亦然。这通常没问题,因为类和协议(protocol)在源代码中的引用方式不同:名为 Foo 的类由裸标识符引用 Foo , 而一个名为 Foo 的协议(protocol)由 @protocol(Foo) 引用.这里没有冲突。
  2. 然而,在 Swift 中,不同类型之间的名称解析没有区别。协议(protocol)名称与所有其他类型名称位于同一命名空间中,引用名为 Foo 的类在语法上没有区别。和一个名为 Foo 的协议(protocol),部分导致上述错误。

请注意,由于 Swift 中的名称解析方式,enum s/struct s/class es 可以与协议(protocol)同名,反之亦然;名称本身在 Swift 中不是唯一的,但完全限定的名称是。你得到上面错误的原因实际上是因为 struct Testprotocol Test将具有相同的完全限定名称:<name-of-your-module>.Test

没有什么可以阻止您声明 struct Testprotocol Test但是,在不同 模块中,因为它们具有不同的完全限定名称。例如,欢迎您添加

struct ExpressibleByStringLiteral {}

到你的代码,尽管标准库提供了一个同名的协议(protocol)。 ExpressibleByStringLiteral然后会隐藏标识符的其他用法,因此要引用 stdlib 提供的协议(protocol),您需要使用 Swift.ExpressibleByStringLiteral 的完全限定名称:

struct ExpressibleByStringLiteral {}
struct S1 : ExpressibleByStringLiteral {} // error: inheritance from non-protocol type 'ExpressibleByStringLiteral'

struct S2 : Swift.ExpressiblyByStringLiteral {} // need to add methods to satisfy the protocol

这对 Swift 中的所有类型都是如此 — 多个类型可以具有相同的名称,只要它们的完全限定名称是唯一的即可。

关于objective-c - 为什么Objective-C类和协议(protocol)可以重名,而Swift不可以,语言实现有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49221554/

相关文章:

iphone - 将 NSManagedObjects 添加到一对多关系

iPhone 在视频播放后强制方向

ios - 将主要的 AppleLanguage 更改为阿拉伯语,但仍然是 UIUserInterfaceLayoutDirectionLeftToRight

swift - 如何在 SwiftUI/Mapkit 中正确显示自定义引脚?

swift - 如何从界面生成器中检索 key

xcode - SQLite.swift 模块文件是由旧版本的编译器创建的

iphone - 如何将 NSDictionary 存储为核心数据中的可转换属性

Iphone 对象 C - 数据、对象和数组

ios - 功能不等待在 Swift 中使用 Alamofire 下载图片

ios - 秒表应用程序不断崩溃