Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
188 views
in Technique[技术] by (71.8m points)

ios - Why must a protocol operator be implemented as a global function?

I've seen the answer to this Swift Equatable Protocol question that mentions how the == method must be declared in the global scope.

If I don't adopt Equatable, I still could declare == to test for equality between two of my types.

// extension Foo: Equatable {}

func ==(lhs: Foo, rhs: Foo) -> Bool {
    return lhs.bar == rhs.bar
}

struct Foo {
    let bar:Int
}

The fact that its implementation needs to be declared at a global scope, makes it seem incidental to and distinct from a protocol, even if Equatable was adopted.

How is the Equatable protocol anything more than syntactic sugar that merely lets (us and) the compiler safely know that our type implemented the required method of the protocol?

Why does the operator implementation have to be globally declared, even for a protocol? Is this due to some different way that an operator is dispatched?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

UPDATE

From the Xcode 8 beta 4 release notes:

Operators can be defined within types or extensions thereof. For example:

struct Foo: Equatable {
    let value: Int
    static func ==(lhs: Foo, rhs: Foo) -> Bool {
        return lhs.value == rhs.value
    }
}

Such operators must be declared as static (or, within a class, class final), and have the same signature as their global counterparts. As part of this change, operator requirements declared in protocols must also be explicitly declared static:

protocol Equatable {
    static func ==(lhs: Self, rhs: Self) -> Bool
}

ORIGINAL

This was discussed on the swift-evolution list recently (2016-01-31 through 2016-02-09 so far). Here's what Chris Lattner said, regarding declaring operators in a struct or class scope:

Yep, this is a generally desirable feature (at least for symmetric operators). This would also be great to get dynamic dispatch of operators within class declarations. I don’t think we have a firm proposal nailing down how name lookup works with this though.

And later (replying to Haravikk):

What are the name lookup issues? Do you mean cases where an operator for Foo == Foo exists in more than one location?

Yes. Name lookup has to have a well defined search order, which defines shadowing and invalid multiple definition rules.

Personally I’d just stick with what we have now, i.e- treat operator implementations within a specific class/struct as being globally defined anyway and throw an error if the same signature is declared more than once.

We need multiple modules to be able to define instances of an operator, we need operators in extensions, and we need retroactive conformance to work, as with any other member.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...