Problem
My goal is to somehow initialize a generic object similar to this:
struct SomeStruct<A, B> where A: View, B: View {
let a: A?
let b: B?
init(a: A? = nil, b: B? = nil) {
self.a = a
self.b = b
}
}
let someStruct: SomeStruct = .init(a: Color.red)
However, this snippet throws an error:
Generic Parameter 'B' Couldn't Be Inferred
Alternative #1: Diamond Notation
One alternative would be specifying Never type in a diamond notation:
let someStruct: SomeStruct<Color, Never> = .init(a: Color.red)
But this is a clunky solution as I don't want to pass types explicitly.
Alternative #2: Constrained Initializers
Another wordy alternative is writing custom initializers, omitting each type by specifying Never type:
struct SomeStruct<A, B> where A: View, B: View {
let a: A?
let b: B?
}
extension SomeStruct where A == Never {
init(b: B) {
self.a = nil
self.b = b
}
}
extension SomeStruct where B == Never {
init(a: A) {
self.a = a
self.b = nil
}
}
extension SomeStruct where A == Never, B == Never {
init() {
self.a = nil
self.b = nil
}
}
let someStruct: SomeStruct = .init(a: Color.red)
But as you can see, this requires a lot of repetitive code. So if I have an object of 10 generic types, this can become a mess.
Question
In short, I am looking for a way to retain a simple initializer, as shown in Problem section. Is there a way to provide a default type to a parameter (Never), as you would usually provide a default value to that parameter?.
No. But everybody wants it (I asked them), and although there has been activity on the Swift forum about it, it hasn't come to pass yet.
Example thread: https://forums.swift.org/t/draft-allow-default-value-for-parameters-in-generic-clause/11200
Aye, this is the state of things. Your problem, and lack of variadics, are the big ones.