Why does Swift BooleanLiteralConvertible require a logical literal?

I am trying to add BooleanLiteralConvertible support for my class so that I can instantiate using a boolean. What throws me into the loop is the difference between a boolean and a boolean literal.

For example, after adding a protocol, I tried to do this:

 func setSelected(value: Bool) { var node: MyClass = value } 

But Swift complained that he could not convert Bool to MyClass . It took me a while to figure out that this should be a logical literal. Oddly enough, the following works just fine:

 func setSelected(value: Bool) { var node: MyClass = value ? true : false } 

... which seems completely stupid to me. Is there a legitimate reason for this seemingly very strange claim?

+6
source share
2 answers

I like the question. Only the Swift command could finally answer, but I can assume why: converting a typed value to a variable of another type without explicit conversion or cast is very easy to confuse with a programmer error, and in many cases this is something the compiler should warn.

Example (and suppose Person also a StringLiteralConvertible , which can be initialized with a string variable as well as a literal, as you present in your question):

 struct Person { private static var idCounter = 1 var name:String let id:Int init(withName name:String) { Person.idCounter += 1 self.name = name self.id = Person.idCounter } } var person = Person(withName:"Mary") let name = "John" person = name 

The above code looks suspiciously like an error when a programmer assigns a value of the wrong type ( String ) to a variable of type Person . This may actually be a mistake. Maybe the programmer just wanted to change the person’s name ( person.name = name ) without creating a new Person with a new unique id. Or perhaps the programmer intended to assign a different value to Person , but made a typo error or a code completion error. It is difficult to say, not being the original programmer, or to carefully study the entire context to understand whether this transformation makes sense. And it gets harder and harder the more the assignment comes from where the variables are initially initialized. If the compiler warns here that a value of type String assigned to a variable of type Person ?

The example will be much clearer and more consistent with Swift conventions like:

 var person = Person(withName:"Mary") let name = "John" person = Person(withName:name) 

The above version is completely unique, both for the compiler and for any other programmers who read this later.

+2
source

Types corresponding to BooleanLiteralConvertible can be initialized with boolean literals true and false , for example.

 let mc : MyClass = true 

This has nothing to do with type initialization using a Boolean value :

 let value : Bool = // ... some boolean value let mc : MyClass = value // error: cannot convert value of type 'Bool' to specified type 'MyClass' 

and there is, as far as I know, no way to make such an implicit change in a work. You will need to write your own init method

 init(bool : Bool) { // ... } 

and initialize the object as

 let value : Bool = // ... some boolean value let mc = MyClass(bool: value) 
+6
source

All Articles