This is (in my opinion) neat part of the language. Yes, this is possible, thanks to the ExpressibleByStringLiteral
protocol.
Unfortunately, there is some complexity to it. ExpressibleByStringLiteral
inherits from ExpressibleByExtendedGraphemeClusterLiteral
, which itself inherits from ExpressibleByUnicodeScalarLiteral
. Thus, to conform to the first, you must conform to the other 2 above it.
This makes it possible for your struct or class to be initialized from:
- A
UnicodeScalarLiteralType
(such as a UnicodeScalar
, which is a single Unicode code point, e.g. "A"
)
- An
ExtendedGraphemeClusterLiteralType
(such as a Character
, which is a collection of UnicodeScalar
s, such as "??"
)
- A
StringLiteralType
(such as String
, which is a collection of Characters
, such as "This is a string"
)
Here's an example implementation that just sets a String
member variable:
struct StringV2: ExpressibleByStringLiteral {
let s: String
init(unicodeScalarLiteral: UnicodeScalar) {
s = String(unicodeScalarLiteral)
}
init(extendedGraphemeClusterLiteral: Character) {
s = String(extendedGraphemeClusterLiteral)
}
init(stringLiteral: String) {
s = stringLiteral
}
}
let s1: StringV2 = "This is a string" // String
print(s1.s)
let s2: StringV2 = "A" // Unicode scalar
print(s2.s)
let s3: StringV2 = "??" // Extended grapheme cluster
print(s3.s)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…