Reputation: 6462
I want to know how Literal Convertibles work in Swift. The little I know is that the fact that, in var myInteger = 5
, myInteger magically becomes an Int
is because Int
adopts a protocol, ExpressibleByIntegerLiteral
and we don't have to do var myInteger = Int(5)
. Similarly String
, Array
, Dictionary
etc all conform to some Literal protocols.
My Question is
class Employee {
var name: String
var salary: Int
// rest of class functionality ...
}
How can I implement Literal Protocols to do var employee :Employee = "John Doe"
which will automatically assign "John Doe" to employee's name property.
Upvotes: 1
Views: 1645
Reputation: 93181
ExpressibleBy...Literal
protocols. When the Swift compiler parses your source code into an Abstract Syntax Tree, it already identified what literal represents what data type: 5
is a literal of type Int
, ["name": "John"]
is a literal of type Dictionary
, etc. Apple makes the base type conform to these protocols for the sake of completeness.For example, if you want to make your class conform to ExpressibleByStringLiteral
, add an initializer to set all your properties from a String
:
class Employee: ExpressibleByStringLiteral {
typealias StringLiteralType = String
var name: String
var salary: Int
required init(stringLiteral value: StringLiteralType) {
let components = value.components(separatedBy: "|")
self.name = components[0]
self.salary = Int(components[1])!
}
}
Then you can init your class like this:
let employee1: Employee = "John Smith|50000"
But if you dream about about writing something like this, it's not allowed:
let str = "Jane Doe|60000"
let employee2: Employee = str // error
And if you pass in the wrong data type for salary
, it will be a run time error instead of a compile-time error:
let employee3: Employee = "Michael Davis|x" // you won't know this until you run the app
TL, DR: it is a very bad idea to abuse these ExpressibleBy...Literal
types.
Upvotes: 2
Reputation: 1373
This can be a scenario to work with Convertibles in custom types.
struct Employee : ExpressibleByStringLiteral {
var name: String = ""
init() {}
init(stringLiteral name: String) {
self.name = name
}
}
func reportName(_ employee: Employee) {
print("Name of employee is \(employee.name)")
}
reportName("John Doe") //Name of employee is John Doe
Upvotes: 0