Distinction in Swift Between Uppercase "Self" and Lowercase "Self"

Distinction in Swift between uppercase Self and lowercase self

Self refers to the type of the current "thing" inside of a protocol (whatever is conforming to the protocol). For an example of its use, see Protocol func returning Self.

The official docs I've found for Self is in Protocol Associated Type Declaration in The Swift Programming Language. It surprisingly is not documented in the sections on protocols or on nested types:

However, now there is a paragraph about Self Type including a code example in the official Swift Programming Language's chapter about Types

How can I invoke a method on `Self` in a Swift extension?

Since allZeros is already a method of Int you can just do it like this:

extension Int {
static var allOnes: Int { return ~allZeros }
}

Why this code capturing self inside this block compile in swift?

The compiler has never complained about this. But it should (and I have filed a bug on this point), because the code you've written won't work: the button will not actually do anything when tapped. (The app might even crash, but then again it might not.)

The reason (for both phenomena) is that the compiler misinterprets the term self here to mean the class — which does exist before initialization of the instance.

The solution is to replace let by lazy var. That does work, because now the code will not actually be called until some later, when the instance does exist.

Better way of using self. in background thread?

You can create a nested function or another method to put the code you want to execute in, then pass that nested function or method into DispatchQueue.main.async.

Here's an example with a nested function:

Original code:

class Foo {
var a = 0
var b = 0
var c = 0

func f() {
a = 1
b = 1
c = 1
}
}

Doing it asynchronously:

class Foo {
var a = 0
var b = 0
var c = 0

func f() {
func doAsync() {
a = 1
b = 1
c = 1
}
DispatchQueue.global(qos: .background).async(execute: doAsync)
}
}

As you can see, you don't need to add any selfs.

The type of self in Swift and its use with respect to two-phase initialization

1)

Shouldn't I get a compiler error if I'm trying to use self too soon?

I do agree. You may send a bug report to swift.org.

Why does the compiler allow us to use self here if self is not ready to be used?

Unfortunately, there's another self in the descendants of NSObject, the method self() of NSObject.

2)

What is that and why does self have two different types within the same class?

The current Swift interprets the initial value expression in the class context, not in the instance context.

You know method names can be used as closures in Swift:

class ViewController: UIViewController {
//..

func aMethod() {
//...
}

func anInstanceMethod() {
let meth = aMethod // () -> ()
}
}

Swift can also refer to an instance method in the class context, which generates a so-called unapplied method reference (see SE-0042), which currently returns a curried function:

class ViewController: UIViewController {
//...

func aMethod() {
//...
}

class func aClassMethod() {
let meth = aMethod // (ViewController) -> () -> ()
}
}

The method self() as well.

Generally we do not need self() method and this behavior should be changed, I think.

How associated(typealias) type and Self in protocols work?

Pro1

Writing this

protocol Pro1 {
typealias Element
}

you are just telling that there will be a type named Element.

Pro2

Adding this

protocol Pro2: Pro1 {
typealias Element = Self
}

you are telling to the compiler that Element will be the same type of the type that is implementing Pro2.

So yes, there is a relation between the Element in Pro1 and Pro2.

Adding methods to Pro1

Let's declare 2 methods that will use Element in Pro1

protocol Pro1 {
typealias Element
func a() -> Element
func b(elm: Element)
}

Conforming to Pro1

Now a class conform to Pro1 will be like this.

class Foo: Pro1 {
func a() -> String {
return ""
}
func b(elm: String) {
}
}

As you can see we are forced by the compiler to set the return type of a and the param of b to be of the same type.

Conforming to Pro2

Now let's try to conform another class to Pro2. Again Pro1 will force us to declare methods a and b where the return type of a is equals to the param of b.
Furthermore Pro2 will force us to set this type equals to the type of the current type Boo.

So the previous class will to conform to Pro2 because String is different from Foo

class Foo: Pro2 {
func a() -> String { // <- compiler error
return ""
}
func b(elm: String) { // <- compiler error

}
}

But if we declare a new class and replace Element with Boo it will work because the constraints of both protocols are satisfied.

class Boo: Pro2 {
func a() -> Boo {
return Boo()
}
func b(elm: Boo) {

}
}

Cannot assign to property: 'self' is immutable swift error

Make the protocol become reference type

protocol Positions: AnyObject {


Related Topics



Leave a reply



Submit