如何在swift中自定义基本类型Bool

Boolean

The boolean Bool type in Swift underlies a lot of primitive functionality, making it an interesting demonstration of how to build a simple type. This post walks through the creation of a new MyBool type designed and implemented to be very similar to the Bool type built into Swift. We hope this walk through the design of a simple Swift type will help you better understand how the language works.

Let’s start with the basic definition. The MyBool type models two different cases, perfect for an enum:

enum MyBool {
	case myTrue, myFalse
}

To reduce confusion in this post, we’ve named the cases myTrue and myFalse. We want MyBool() to produce a false value, and can do so by providing an init method:

extension MyBool {
	init() { self = .myFalse }
}

Swift enum declarations implicitly scope their enumerators within their body, allowing us to refer toMyBool.myFalse and even .myFalse when a contextual type is available. However, we want our type to work with the primitive true and false literal keywords. To make this work, we can make MyBoolconform to the BooleanLiteralConvertible protocol like this:

extension MyBool : BooleanLiteralConvertible {
	static func convertFromBooleanLiteral(value: Bool) -> MyBool {
		return value ? myTrue : myFalse
	}
}

// We can now assign 'true' and 'false' to MyBool.
var a : MyBool = true

With this set up, we have our basic type, but we still can’t do much with it. Booleans need to be testable within an if condition. Swift models this with the BooleanType protocol, which allows any type to be used as a logical condition:

extension MyBool : BooleanType {
	var boolValue: Bool {
		switch self {
		case .myTrue: return true
		case .myFalse: return false
		}
	}
}

// Can now test MyBool in 'if' and 'while' statement conditions.
if a {}

We also want anything that conforms to BooleanType to be castable to MyBool, so we add:

extension MyBool {
	// MyBool can be constructed from BooleanType
	init(_ v : BooleanType) {
		if v.boolValue {
			self = .myTrue
		} else {
			self = .myFalse
		}
	}
}

// Can now convert from other boolean-like types.
var basicBool : Bool = true
a = MyBool(basicBool)

Note that the use of _ in the initializer argument list disables the keyword argument, which allows theMyBool(x) syntax to be used instead of requiring MyBool(v: x).

Now that we have basic functionality, let’s define some operators to work with it, starting with the ==operator. Simple enums that have no associated data (like MyBool) are automatically made Equatableby the compiler, so no additional code is required. However, you can make arbitrary types equatable by conforming to the Equatable protocol and implementing the == operator. If MyBool weren’t alreadyEquatable, this would look like this:

extension MyBool : Equatable {
}

func ==(lhs: MyBool, rhs: MyBool) -> Bool {
	switch (lhs, rhs) {
	case (.myTrue,.myTrue), (.myFalse,.myFalse):
		return true
	default:
		return false
	}
}

// Can now compare with == and !=
if a == a {}
if a != a {}

Here we’re using some simple pattern matching in the switch statement to handle this. Since MyBool is now Equatable, we get a free implementation of the != operator. Lets add binary operations:

func &(lhs: MyBool, rhs: MyBool) -> MyBool {
	if lhs {
		return rhs
	}
	return false
}

func |(lhs: MyBool, rhs: MyBool) -> MyBool {
	if lhs {
		return true
	}
	return rhs
}

func ^(lhs: MyBool, rhs: MyBool) -> MyBool {
	return MyBool(lhs != rhs)
}

With the basic operators in place, we can implement a variety of helpful unary and compound assignment operators as well, for example:

prefix func !(a: MyBool) -> MyBool {
	return a ^ true
}

// Compound assignment (with bitwise and)
func &=(inout lhs: MyBool, rhs: MyBool) {
	lhs = lhs & rhs
}

The &= operator takes the left operand as inout because it reads and writes to it, and the effect must be visible to the user of the operator. Swift gives you complete control over mutability of operations on value types like enum and struct.

With this, the simple MyBool type has all of the basic operations and operators. Hopefully this post gives you a few tips that you can apply to your own code when defining higher-level types.


转载自Apple Swift Blog:https://developer.apple.com/swift/blog/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值