您的位置:首页 > 移动开发 > Swift

Swift基础之Literal的简单使用

2017-07-07 15:49 323 查看
自2012年以来,可以使用 “literal” 表达式初始化NSDictionary,NSArray,NSNumber或NSString。
NSNumber *numb = @1;
NSArray *things = @[@3,@45,@65];
NSDictionary *map = @{@"Florida" : @1 , @"Nevada" : @6 };
NSString *greet = @"Hello there!";
这种 “literal” 表达式让代码变得更加简洁。你有没有想过使用 “literal” 表达式来初始化自己的数据结构。Swift 中提供了 “ExpressibleBy _____” 这类协议:Expressible By Array Literal
Expressible By Boolean Literal
Expressible By Dictionary Literal
Expressible By Float Literal
Expressible By Integer Literal
Expressible By String Literal
Expressible By Unicode Scalar Literal
Expressible By Extended Grapheme Cluster Literal
可以使用 “literal” 表达式来初始化自己的数据结构,可以看看下面的例子,如何使用 “literal” 表达式来构建自己的数据结构。

Array-ish 数据结构

来看看 Swift 中的例子, [1,2,3,4,5,6,7,8] 这很可能用于初始化一个 Array。但是!他也可以用于初始化成其他的数据结构。链表下面这段代码就是介绍如何使用 Array literal 来初始化一个链表:
class LinkedList<T> : ExpressibleByArrayLiteral, CustomDebugStringConvertible {
var debugDescription: String {
get {
var accum = ""
guard let startNode = self.head else { return "(empty list)" }
accum += startNode.debugDescription
var currentNode:Node = startNode
while(true) {
guard let node = currentNode.next else { break }
accum += node.debugDescription
currentNode = node
}
return accum
}
}
var head:Node?
var tail:Node?
typealias Element = T
required public init(arrayLiteral elements:Element...) {
for i in elements {
if self.head == nil {
self.head = Node(data:i)
self.tail = self.head
continue
}
let newNode = Node(data:i)
self.tail?.next = newNode
self.tail = newNode
}
}
class Node : CustomDebugStringConvertible {
var debugDescription: String {
get {
var accum = "(\(data))->"
if next == nil {
accum += "*"
}
return accum
}
}
var next:Node?
var data:T
init(data:T) {
self.data = data
}
}
}
let link:LinkedList<Int> = [1,2,3,4,5,6,7,8]
print(link)   // Prints (1)->(2)->(3)->(4)->(5)->(6)->(7)->(8)->*
LinkedList 类遵从 ExpressibleByArrayLiteral 协议,实现 init(arrayLiteral: Self.Element...) 这个初始化方法, 那么我们就可以直接使用 Array literal 赋值进行初始化。
let link:LinkedList<Int> = [1,2,3,4,5,6,7,8]
注意:必须使用 Array literal 来赋值,而不能用一个数组赋值,因为这是两个不同的东西,例如:
let someArray = [1,2,3,4]
let list:LinkedList<Int> = someArray  // 这段代码会报错。

堆栈
struct ConvertibleStack<T> : ExpressibleByArrayLiteral, CustomDebugStringConvertible {

var debugDescription: String {
get {
return "Stack: \(storage)"
}
}
typealias Element = T
private var storage: [T] = []

public init(arrayLiteral elements:Element...) {
self.storage = elements
}

mutating func push(item:T) {
storage.insert(item, at: 0)
}

mutating func pop() -> T? {
guard storage.count > 0 else { return nil }
return storage.remove(at: 0)
}
}

队列
struct ConvertibleStack<T> : ExpressibleByArrayLiteral, CustomDebugStringConvertible {

var debugDescription: String {
get {
return "Stack: \(storage)"
}
}
typealias Element = T
private var storage: [T] = []

public init(arrayLiteral elements:Element...) {
self.storage = elements
}

mutating func push(item:T) {
storage.insert(item, at: 0)
}

mutating func pop() -> T? {
guard storage.count > 0 else { return nil }
return storage.remove(at: 0)
}
}
最后,如果正确的使用 litera 初始化可以提高可读性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  swift Literal 协议