SoFunction
Updated on 2025-04-10

Detailed explanation of Swift type creation: Customize a type

Friends, the Bool type in Swift has very important syntax functions and supports the logical judgment system in the entire Swift system. After the research and learning of old codes, the Bool type itself is actually a package of the basic Boolean type. Friends may bite their fingers and ask about the old codes. Why do you find the Bool type and the Boolean type? The difference is that the former is a combination type based on enumerations, while the latter is a basic type, with only two true and false.

####Custom Prototype

Next, the old code creates an OCBool ​​type based on Bool's ideas to let friends understand how to play in Swift.

Let’s first look at the definition of OCBool.

The ##### code example is as follows:

Copy the codeThe code is as follows:

enum OCBool{
case ocTrue
case ocFalse
}

#####Notice:

Line 2 and line 3 in the code can be combined into one line, as written by Apple's official blog
Note that when naming in the code: OCBool ​​is a type name, so the initial letter must be uppercase, while ocTrue and ocFalse in case are small types, so the initial letter needs lowercase.

####Implement default values

Yes, we gave a nice definition, but according to traditional language experience, the Bool value is false by default, so the same should be true for our OCBool. We use type extension technology to add this default feature:

Copy the codeThe code is as follows:

extension OCBool{
     init(){
             self =.ocFalse
     }
}

#####Notice:

●Line 1 in the code: extension keyword, very powerful. Friends can create many fun things through this. I suggest you go to Github to see a project called "Swiftz" that will be used to the extreme.

●Line 3 in the code: self = .ocFalse syntax. Friends who are just getting started are confused. Why are there strange point syntax? Because Chris, a big giant, added a type intelligent inference function to Swift. In Apple Blog, the concept of "Context" is mentioned, which is this meaning, because this line statement is enumerated in OCBool, and its context is the definition body of OCBool. The compiler of course knows that .ocFalse is just, so the syntax is directly pointed here, which is very neat.

Now we can use this Bool type using the following method.

The ##### code example is as follows:

Copy the codeThe code is as follows:

var result:OCBool = OCBool()
var result1:OCBool = .ocTrue

####Support basic boolean initialization

As mentioned above, we can only assign values ​​through types or enumeration items. This is the usage of combining types, but in the days of encoding, we always want to deal with true and false directly, that is, we want to do this,

The code example is as follows:

Copy the codeThe code is as follows:

var isSuccess:OCBool = true

If you use this directly, the following error will appear:
Copy the codeThe code is as follows:

/Users/tyrion-OldCoder/Documents/Learning/BoolType/BoolType/:30:24: Type 'OCBool' does not conform to protocol 'BooleanLiteralConvertible'

The reason why the compiler rant is that our types do not comply with the "Boolean literal conversion protocol", and the next step is to fix this problem,

The ##### code example is as follows:

Copy the codeThe code is as follows:

import Foundation

println("Hello, World!")

enum OCBool{
    case ocTrue
    case ocFalse
}


extension OCBool: BooleanLiteralConvertible{
static func convertFromBooleanLiteral( value: Bool) ->OCBool{
    return value ? ocTrue : ocFalse
    }
}

var isSuccess:OCBool = true

#####Notice:

Line 11 in the code is the key point. My type OCBool ​​supports the BooleanLiteralConvertible protocol. What exactly does this cooperation do? Friends, in the Xcode code editor, press and hold the Command key, and then click the BooleanLiteralConvertible protocol name in line 11, and it will enter its definition.

####It is defined as follows:

Copy the codeThe code is as follows:

protocol BooleanLiteralConvertible {
    typealias BooleanLiteralType
    class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self
}

There is a class method convertFromBooleanLiteral in this definition. Its parameter is BooleanLiteralType type, which is the Bool type I passed in. The return value is the type itself that implements this protocol. In our OCBool ​​type, its return value is OCBool ​​itself. Through this definition, we can directly initialize the OCBool ​​type Boolean literals.

####Support Bool type judgment

Friends are restless, and I must be thinking about how I use it to make logical judgments, so if you write this,
The ##### code example is as follows:

Copy the codeThe code is as follows:

var isSuccess:OCBool = true

if isSuccess {
println( "Old code invites you to hot pot!")
}


You will never have the old hotpot, because the compiler here will roar:
Copy the codeThe code is as follows:

/Users/tyrion-OldCoder/Documents/Learning/BoolType/BoolType/:27:4: Type 'OCBool' does not conform to protocol 'LogicValue'

OCBool ​​can only be initialized with bool type, but cannot directly return to bool type. The little torches still remember that in "Old Code Programming: Swift Jianghu", Lao Code mentioned many times that my mother no longer worrys about the way we write if a = 1{}, because the equal sign does not support the return value, so the condition after the if judgment is that there must be a return value, and OCBool ​​does not, so the compiler cried. We solve this problem.
The ##### code example is as follows:

Copy the codeThe code is as follows:

import Foundation

println("Hello, World!")

enum OCBool{
    case ocTrue
    case ocFalse
}


extension OCBool: BooleanLiteralConvertible{
static func convertFromBooleanLiteral( value: Bool) ->OCBool{
    return value ? ocTrue : ocFalse
    }
}

extension OCBool: LogicValue{
    func getLogicValue() ->Bool {
        var boolValue: Bool{
        switch self{
        case .ocTrue:
            return true
        case .ocFalse:
            return false
            }
        }
        return boolValue
    }
}


var isSuccess:OCBool = true

if isSuccess {
println( "Old code invites you to hot pot!")
}

####The running results are as follows:

Copy the codeThe code is as follows:

Hello, World!
Laoma invites you to hot pot!
Program ended with exit code: 0

#####Notice:

●If you are using the Beta version of Xcode now, please note that in the official Apple blog, if it is wrong under Xcode Beta4 in line 17 of the code, the protocol here is LogicValue instead of BooleanVue, so remember to see the error prompts as a good habit.

● Pay attention to line 34 of the code, perfectly supports if judgment, and the output result is "Old code invites you to hot pot". Old code is just a saying, please don't take it seriously.

####Support compatible with each genre

Friends, there are many sects, and old codes have their own OCBool ​​type. Maybe Songshan Shaolin has its own SSBool type, and even Guo Meimei may have its own MMBool type. Therefore, OCBool ​​must be able to recognize these types. As long as these types of various sects support the LogicValue protocol, they should be recognized. See how old codes do it.

The ##### code example is as follows:

Copy the codeThe code is as follows:

extension OCBool{
    init( _ v: LogicValue )
    {
        if (){
            self = .ocTrue
        }
        else{
            self = .ocFalse
        }
    }

}

var mmResult: Bool = true
var ocResult:OCBool = OCBool(mmResult)


if ocResult {
println( "The old code has no money, Guo Meimei invites you to hot pot!")
}

The code running results are as follows:

Copy the codeThe code is as follows:

Hello, World!
The old code has no money, Guo Meimei invites you to hot pot!
Program ended with exit code: 0

pretty! Our OCBool ​​type now supports all logical variable initialization.

#####Notice:

●Line 2 in the code: The usage of the horizontal bar under "_", this is a powerful little strongman. The purpose here is to block external parameter names, so friends can directly: var ocResult: OCBool ​​= OCBool(mmResult) instead of: var ocResult: OCBool ​​= OCBool(v: mmResult), friends were stunned! There is no external parameter name in this init function. Remember that the old code said in the book that Swift's initialization function will use internal parameter names by default as external parameter names.

#### Improve the Boolean gene system of OCBool:
Friends, the value of the bool type lies in various judgments, such as ==, !=, &,|,^,!, and various combinational logic operations. Our OCBool ​​also needs to have these functions, otherwise there will be genetic defects, and it depends on how the old code is implemented:

Copy the codeThe code is as follows:

extension OCBool: Equatable{
}

//Support equivalence judgment operator
func ==( left: OCBool, right: OCBool )->Bool{
    switch (left, right){
    case (.ocTrue, .ocTrue):
            return true
    default:
        return false
    }
}
//Support bit and operator
func &( left:OCBool, right: OCBool)->OCBool{

    if left{
        return right
    }
    else{
        return false
    }
}
//Support bit or operator
func |( left:OCBool, right: OCBool)->OCBool{

    if left{
        return true
    }
    else{
        return right
    }
}

//Support the bit exclusive or operator
func ^( left:OCBool, right: OCBool)->OCBool{
    return OCBool( left != right )
}
//Support inverse operator request
@prefix func !( a:OCBool )-> OCBool{
    return a ^ true
}
//Support combination request and operator
func &= (inout left:OCBool, right:OCBool ){
    left = left & right
}


var isHasMoney:OCBool = true
var isHasWife:OCBool = true
var isHasHealty:OCBool = true
var isHasLover:OCBool = true

isHasMoney != isHasHealty
isHasHealty == isHasMoney
isHasWife ^ isHasLover
isHasWife = !isHasLover

if (isHasMoney | isHasHealty) & isHasHealty{
println( "The winner in life is like the old code!")
}else
{
println("The most difficult thing in life is that when a person dies, money is gone, and the most difficult thing in life is that when a person lives, money is gone!")
}


Okay, that's it here. The thunder outside the window woke up the old code. Now it should be a meal. The above old code shows you that if you create your own type, remember that the example of the old code was tested under Xcode6 Beta4. As for the changes in Beta5, it has not been involved. Friends should practice well. In the future, all kinds of custom types will be based on this idea. There is also this chapter that is not original by Laoma. Laoma has carefully read Apple's official blog and has summarized his own exercises.