'Self' is only available in a protocol or as the result of a class method

marcprux

Update: Swift 3 permits Self to be used from other types, thanks to SE-0068 – Expanding Swift Self to class members and value types.

You can return "Self" from a class function:

extension NSObject {
    class func makeOne() -> Self {
        return self()
    }
}

So you can do:

let set : NSCountedSet = NSCountedSet.makeOne()

However, the following two don't compile:

extension NSObject {
    class func makeTwo() -> (Self, Self) {
        return (self(), self())
    }

    class func makeMany() -> [Self] {
        return [self(), self(), self(), self(), self()]
    }
}

The error is:

<REPL>:11:34: error: 'Self' is only available in a protocol or as the result of a class method; did you mean 'NSObject'?
        class func makeTwo() -> (Self, Self) {
                                 ^~~~
                                 NSObject
<REPL>:11:40: error: 'Self' is only available in a protocol or as the result of a class method; did you mean 'NSObject'?
        class func makeTwo() -> (Self, Self) {
                                       ^~~~
                                       NSObject
<REPL>:15:35: error: 'Self' is only available in a protocol or as the result of a class method; did you mean 'NSObject'?
        class func makeMany() -> [Self] {
                                  ^~~~
                                  NSObject

Does anyone know of any way to declare that a class function returns multiple instances of the class itself?

matt

The problem, I suspect, is that Self is ambiguous; it means "this class or a subclass, whatever the thing happens to be at the time we are called". In other words, Self is polymorphic. But you can't make an array consisting of two different classes, for example. And although the class may permit a certain initializer, we cannot know in advance that its subclass will.

The solution is to use the class name itself. Here's an example for a struct Thing:

extension Thing {
    static func makeTwo() -> (Thing, Thing) {
        return (Thing(), Thing())
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Swift protocol defining class method returning self

Python error: This method is only available to the class, not on instances

Method in non-final class must return `Self` to conform to protocol

How can i make a method available only from within the class

Protocol for class method

Calling instance method of class from another another containing only self

Not able to pass self (which implements a protocol) to init method of a class instantiation.(Swift)

Protocol requirement cannot be satisfied by a non-final class because it uses 'Self' in a non-parameter, non-result type

Save the result of a method in a class

Class method decorator with self arguments?

Class method decorator with self arguments?

Class method: 'self' not being read

Self unpickling in class method in python

self is not defined in class method argument

Self is not passed to the class method in Python

How to make some protocol methods only available for specific iOS version?

iOS: Concurrency is only available in iOS 15.0.0 or newer in protocol

Swift Class Extension Only When Conforming to Protocol

Swift extension only when conforming to Class AND protocol

Self in protocol

Custom method on class that conforms to MKAnnotation protocol

Class Method Swapping Keeping Old Class 'Self'?

what are the reason that method all() inside my class User fetch only on result?

Cache a result set for a class method?

Protocol with property of type Self can only be used as generic constraint, why?

Why is this const only available within the method that calls it?

Protocol extension default method causing a "self is immutable" error

Implementing protocol static method that takes and returns Self (in swift)

Why does Swift disallow assignment to self in class init, but not in protocol init?

TOP Ranking

HotTag

Archive