Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generic type conforming to a protocol in Swift

Is it possible to require that specific instantiations of generic types conform to a protocol in Swift?

For example, say I have a generic type called Thing<T>. I want Thing<Int> to conform to a certain protocol, but not Thing<T>.

like image 664
cfischer Avatar asked Oct 14 '14 09:10

cfischer


People also ask

What is generic protocol in Swift?

Swift enables us to create generic types, protocols, and functions, that aren't tied to any specific concrete type — but can instead be used with any type that meets a given set of requirements.

Which of the following are generic types in Swift?

Swift 4 language provides 'Generic' features to write flexible and reusable functions and types. Generics are used to avoid duplication and to provide abstraction. Swift 4 standard libraries are built with generics code. Swift 4s 'Arrays' and 'Dictionary' types belong to generic collections.

How do I call a generic function in Swift?

Solution. A generic function that you might need to use explicit specialization is the one that infer its type from return type—the workaround for this by adding a parameter of type T as a way to inject type explicitly. In other words, we make it infer from method's parameters instead.


2 Answers

Well, it might not be too onerous, and it might be obvious enough that you've ignored it, but you could make a 'specific instantiation of a generic type' - as:

class ThingOfInt : Thing<Int>, SpecialIntProtocol {
 // implement SpecialIntProtocol (if it isn't already 
 // implemented in an extension)
}

or with a bit more generality:

class IntThing<T:IntegerType> : MyThing<T>, SpecialIntProtocol {
}
like image 160
GoZoner Avatar answered Oct 18 '22 21:10

GoZoner


In Swift 2.0 you can extend protocols and types

When you extend it you can add a generic where constraints. Only types that matches that rule will be able to use that functionality

Example:

public struct Thing<T> {
  let x: T
}

extension Thing where T : IntegerType {
  func giveMeInt () -> T {
    return x
  }
}

let a = Thing<Int>(x: 10)
a.giveMeInt()

let b = Thing(x: 10.1)
//b.giveMeInt() // Error

This way you can add an extra functionality to Thing<Int> type

I don't know a way to conform to a protocol in the extension, but it doesn't make much sense.

Limitation: Generic where T : can be used with protocols and classes, that's why we can't specify Int there

like image 42
Kostiantyn Koval Avatar answered Oct 18 '22 21:10

Kostiantyn Koval