Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why is unresolved generic type legal in a generic?

Tags:

generics

swift

Perhaps I'm being extremely dense, and I realize I'm supposed to know about this sort of thing, but I was taken by surprise by this:

class Wrapper<T> {
    let value: T
    var wrapper: Wrapper? // ok
    init(value: T) {
        self.value = value
    }
}
class Thing {
    var wrapper: Wrapper? // error
}

The error is that inside class Thing I have to resolve the Wrapper generic when I declare the type; I need to say, for instance,

var wrapper: Wrapper<String>?

Why is legal to declare that a property has type Wrapper plain and simple inside a Wrapper but not elsewhere? What makes the declaration inside Wrapper okay? Is it because the compiler just assumes that inside Wrapper, Wrapper means Wrapper<T>?

like image 761
matt Avatar asked Mar 24 '21 18:03

matt


People also ask

Is undefined for the type T Java?

Since T could be String , or Number , or some other random object that somebody else created, you can't assume it will have any particular methods on the object. Therefore, the method base() is undefined for the type T , since T is not necessarily a type that has a base() method.

What Cannot be Parameterized with a type Using generics?

Correct Option: C. Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type.


Video Answer


1 Answers

In the case of Wrapper, T is known, as it's part of Wrapper's definition, so use of Wrapper without specialization is implicitly assumed to be Wrapper<T>

In the case of Thing, there is no T defined, and even if there were, it would not be the same T as in Wrapper. Think of it being analogous to these functions:

func foo(_ x: Int) {
   // x is known here
}

func bar() {
   // x is unheard of here.
}

func foobar(_ x: Int) {
   // x is known here, but it's not the same x as in foo
}

Of course the difference is that even foo has to refer to x explicitly, whereas Wrapper can infer T within its own definition. In fact, if Wrapper wants to refer to another Wrapper that's specialized on a different type, it has to be explicit about it:

class Wrapper<T> {
   ...
   func someConversion<U>(otherWrapper: Wrapper<U>) {
   }
}

Thing on the other hand is declared outside of Wrapper, so it doesn't know about T. So from its perspective

var wrapper: Wrapper?

is just as meaningless as

var values: Array?

The compiler can't create an array if it doesn't know the Element type. Neither can it create your Wrapper without knowing what T is.

like image 124
Chip Jarred Avatar answered Sep 27 '22 20:09

Chip Jarred