Multiple Type Constraints in Swift
You can use a where clause which lets you specify as many requirements as you want (all of which must be fulfilled) separated by commas
Swift 2:
func someFunc<T where T:SomeProtocol, T:SomeOtherProtocol>(arg: T) {
// stuff
}
Swift 3 & 4:
func someFunc<T: SomeProtocol & SomeOtherProtocol>(arg: T) {
// stuff
}
or the more powerful where clause:
func someFunc<T>(arg: T) where T:SomeProtocol, T:SomeOtherProtocol{
// stuff
}
You can of course use protocol composition (e.g., protocol<SomeProtocol, SomeOtherProtocol>
), but it's a little less flexible.
Using where
lets you deal with cases where multiple types are involved.
You may still want to compose protocols for reuse in multiple places, or just to give the composed protocol a meaningful name.
Swift 5:
func someFunc(arg: SomeProtocol & SomeOtherProtocol) {
// stuff
}
This feels more natural as the protocols are next to the argument.
Multiple Type Constraints
You could use an if statement when your method is called. Then have two different versions of the method (one for each type of constraint) and depending on which constraint you need to use, call the appropriate method.
More than one protocol in a type constraint
you can use this workaround
class MyCustomClass<T: Equatable where T: IndexableBase > {
var a: Array<T>
init() {
a = Array<T>()
}
}
Swift 4:
class MyCustomClass<T: Equatable> where T: Collection {
var a: Array<T>
init() {
a = Array<T>()
}
}
Multi-level generic type constraints in Swift
I'm not sure if that's what you're looking for, but you can do it using a protocol with associated type:
struct Foo<T> { }
protocol BarProtocol {
associatedtype U: Codable
}
struct Bar<U: Codable>: BarProtocol {
}
// Now this works
extension Foo where T: BarProtocol {
// T.U can be of any type that implements Codable
}
Edit - Changed to T: BarProtocol, thanks Marcel!
How to add multiple generic type constraints in Swift?
Put it like this instead,
TableViewDataSource
<Model:ManagedObject, Cell: UITableViewCell
where Model:ManagedObjectType, Cell:ConfigurableCell>:
NSObject,UITableViewDataSource
All generic types should to be first declared separated with delimeter(comma) and then constraints should be provided later and each constraint also should be separated with comma. All the constraints has to be fulfilled in order for it to work.
Multiple constraints on parameter of a generic function
Actually You can do that.
If you have seen Codable
in swift it is actually Decodable
and Encodable
typealias Codable = Decodable & Encodable
So in some function if you are using generic T as Codable
struct StructOfCodable<T:Codable>: Codable {
....
}
Here is example
protocol Test {}
class TClass {
}
typealias Common = Test & TClass
func generic <T:Common>(method:T) {
}
Another way is protocol and class both can have super class. So you can create common protocol
like
protocol CommonInProtocolAndStruct { }
protocol ProtocolUsedAsConstraint:CommonInProtocolAndStruct {}
struct StructUsedAsConstraint:CommonInProtocolAndStruct {}
And any method you can use CommonInProtocolAndStruct
as generic constraint
Complex extensions with multiple type constraints
Yes, you are nearly there!
KeyedDecodingContainer
doesn't have aRawValue
type, it'sK
that does, asK
conforms toRawRepresentable
AnyHashable
is a concrete implementation ofHashable
. UseHashable
when you want to constrain generic parameters.KeyedDecodingContainer<K>.Key
can be simplified to justKey
, since you are in the scope ofKeyedDecodingContainer<K>
.- You don't need
as Any
. Everything can be implicitly converted toAny
.
extension KeyedDecodingContainer where K : CodingKey,
K : RawRepresentable,
K.RawValue : Hashable {
/// A helper method
func decode<T>(into object: inout [K.RawValue : Any], _ type: T.Type,
forKey key: Key) throws where T : Decodable {
object[key.rawValue] = try self.decode(type, forKey: key)
}
}
Related Topics
Swift: How to Detect Linear Type Barcodes
In Swift 3, What Is a Way to Compare Two Closures
Open Uidatepicker Programmatically in iOS 14
What's the Difference Between Aranchor and Anchorentity
Using Foreach Loop with Binding Causes Index Out of Range When Array Shrinks (Swiftui)
Ambiguous Reference to Member 'Tableview'
How to Make an Array of the Current Week Dates Swift
How to Print Out the Method Name and Line Number in Swift
Swiftui Create Image Slider with Dots as Indicators
Include Swiftui Views in Existing Uikit Application
Use Reserved Keyword a Enum Case
Setting the Timelineprovider Refresh Interval For Widget
Convert a Swift Array of String to a to a C String Array Pointer
Xcode 7.3/Swift 2: "No Method Declared with Objective-C Selector" Warning
Is There a Prefix Header (Or Something with This Functionality) in Swift