Swift, Can't compile, compiler will directly report error.
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, Can be compiled successfully, for example NSObject is a class name, it is also a protocol name
#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
In Objective-C, protocols are declared with the “@protocol” keyword. Below is an example of declaring a protocol containing one required method. In Swift, the syntax is a little different but the idea is the same. In Objective-C, you add the protocol name in angle brackets beside the class interface declaration.
You can work with types declared in Swift from within the Objective-C code in your project by importing an Xcode-generated header file. This file is an Objective-C header that declares the Swift interfaces in your target, and you can think of it as an umbrella header for your Swift code.
Swift checks for protocol conformity issues at compile-time, allowing developers to discover some fatal bugs in the code even before running the program. Protocols allow developers to write flexible and extensible code in Swift without having to compromise the language's expressiveness.
Protocol is a set of methods (either optional or required) that would be implemented by the class which conforms to that protocol. While, delegate is the reference to that class which conforms to that protocol and will adhere to implement methods defined in protocol.
Objective-C and Swift have different name resolution schemes which cause this to happen.
Foo
is referred to by the bare identifier Foo
, while a protocol named Foo
is referred to by @protocol(Foo)
. There's no clashing here.Foo
and a protocol named Foo
, partially leading to the error above.Note that because of how name resolution happens in Swift, enum
s/struct
s/class
es can have the same names as protocols, and vice versa; names themselves are not unique in Swift, but fully-qualified names are. The reason you get the error above is actually because both struct Test
and protocol Test
would have the same fully-qualified name: <name-of-your-module>.Test
There is nothing preventing you from declaring struct Test
and protocol Test
in different modules, though, since they'd have different fully-qualified names. For instance, you're welcome to add
struct ExpressibleByStringLiteral {}
to your code, despite a protocol by that name being offered by the standard library. ExpressibleByStringLiteral
would then shadow other usages of the identifier, so to refer to the protocol provided by the stdlib, you'd need to use the fully-qualified name of 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
This is true for all types in Swift — multiple types can have the same name as long as their fully-qualified names are unique.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With