young
(rtSwift)
1
struct Foo: ExpressibleByStringLiteral {
init(stringLiteral value: String) /* throws :( not allow? */ {
guard value == "good" else {
// how to fail?
// neither failable or throws seem to be allowed?
fatalError("Ha? what to do here, want to fail somehow, not crash!!!")
}
// okay, we are good ...
}
}
basically Foo init by string literal only works for some string values, else it needs to fail somehow.
1 Like
fatalError is the best you can do for now. Hopefully optimizer improvements will eventually allow literals to be evaluated as compile‐time constants, which would elevate the fatalError to an outright build failure.
2 Likes
xAlien95
(Stefano De Carolis)
3
How would a throwing assignment work? Where should you put try?
do {
// here?
try let foo: Foo = "good"
// or maybe here?
let foo: Foo = try "good"
} catch { }
I don't see a workable solution from the syntactic standpoint alone.
A solution that may work for your use case: mimicking a failable initializer.
public struct Foo {}
extension Optional: ExpressibleByStringLiteral,
ExpressibleByUnicodeScalarLiteral,
ExpressibleByExtendedGraphemeClusterLiteral where Wrapped == Foo {
public init(stringLiteral value: String) {
guard value == "good" else {
self = nil
return
}
// okay, we are good ...
self = Foo()
}
public init(unicodeScalarLiteral value: String) {
self = .init(stringLiteral: value)
}
public init(extendedGraphemeClusterLiteral value: String) {
self = .init(stringLiteral: value)
}
}
let foo: Foo? = "bad" // assigns nil
let bar: Foo? = "good" // assigns Foo()
2 Likes
Nevin
4
One thing you could do is make Optional<Foo> conform to the Expressible protocol, rather than Foo itself.
4 Likes