枚举的成员值是实际值,并不是原始值的另一种表达方法。 可以尝试打印生成的枚举就是该值本身,而打印rawValue后才是对应的type的值
处理错误:
1Throw Throws Do Catch
2try?
将结果转换为可选的。如果函数抛出错误,该错误会被抛弃并且结果为nil。否则的话,结果会是一个包含函数返回值的可选值。
1 第一种方式
enum myError: Error{
case OutOfPaper
case NoToner
case OnFire
}
func sendToPrinter(pointerName: String) throws -> String {
if pointerName == "NeverHasToner" {
throw myError.NoToner
}
defer {
print("不管方法是否被throw抛错阻止都会走进来 defer是函数终止前执行的最后一段代码 不因throw而影响")
}
return "Yes It is me"
}
do {
let valueThrowing = try sendToPrinter(pointerName: "NeverHasToner")
print(valueThrowing)
} catch myError.OnFire {
print("Catch的东西就是你throw出来的东西 因此你可以进行判断和自定义")
}
catch let myOwnErrorNow as myError {
print("我自己的错误类型**********\(myOwnErrorNow)")
}
catch {
print("系统默认的错误类型********\(error)")
}
2 第二种方式
let canThrowError = try? sendToPrinter(pointerName: "NeverHasToner---")
let canThrowError = try? sendToPrinter(pointerName: "NeverHasToner")
3 与系统关键字冲突时使用 let let
= "dkfjdkfj"; print(let
)
4 浮点类型 Float
浮点字面量可以是十进制(没有前缀)或者是十六进制(前缀是 0x )。小数点两边必须有至少一个十进制数字(或者是十六进制的数字)。十进制浮点数也可以有一个可选的指数(exponent),通过大写或者小写的 e 来指定;十六进制浮点数必须有一个指数,通过大写或者小写的 p 来指定。
如果一个十进制数的指数为 exp,那这个数相当于基数和10^exp的乘积:
1.25e2 表示 1.25 × 10^2,等于 125.0。
1.25e-2 表示 1.25 × 10^-2,等于 0.0125。
如果一个十六进制数的指数为exp,那这个数相当于基数和2^exp的乘积:
0xFp2 表示 15 × 2^2,等于 60.0。
0xFp-2 表示 15 × 2^-2,等于 3.75。
5 断言保证前面的表达式必须要通过 不然后面就会是表达式 assert(1 > 2, "Imposible")
6 Swift 的String类型是基于 Unicode 标量 建立的。 Unicode 标量是对应字符或者修饰符的唯一的21位数字.Unicode 标量,写成\u{n}(u为小写),其中n为任意一到八位十六进制数且可用的 Unicode 位码。let sparklingHeart = "\u{1F496}" // 💖, Unicode 标量 U+1F496
7 字符串的标量
每一个 Swift 的Character类型代表一个可扩展的字形群。 一个可扩展的字形群是一个或多个可生成人类可读的字符 Unicode 标量的有序排列。 举个例子,字母é可以用单一的 Unicode 标量é(LATIN SMALL LETTER E WITH ACUTE, 或者U+00E9)来表示。然而一个标准的字母e(LATIN SMALL LETTER E或者U+0065) 加上一个急促重音(COMBINING ACTUE ACCENT)的标量(U+0301),这样一对标量就表示了同样的字母é。 这个急促重音的标量形象的将e转换成了é。在这两种情况中,字母é代表了一个单一的 Swift 的Character值,同时代表了一个可扩展的字形群。 在第一种情况,这个字形群包含一个单一标量;而在第二种情况,它是包含两个标量的字形群: 但无论怎样在 Swift 都会表示为同一个单一的Character值
8 想要获得一个字符串中Character值的数量,可以使用字符串的characters属性的count属性。在 Swift 中,使用可拓展的字符群集作为Character值来连接或改变字符串时,并不一定会更改字符串的字符数量。所以字符在一个字符串中并不一定占用相同的内存空间数量。通过characters属性返回的字符数量并不总是与包含相同字符的NSString的length属性相同。NSString的length属性是利用 UTF-16 表示的十六位代码单元数字,而不是 Unicode 可扩展的字符群集。作为佐证,当一个NSString的length属性被一个Swift的String值访问时,实际上是调用了utf16Count。
var word = "cafe"
print("the number of characters in \(word) is \(word.characters.count)")
// 打印输出 "the number of characters in cafe is 4"
word += "\u{301}" // COMBINING ACUTE ACCENT, U+0301
print("the number of characters in \(word) is \(word.characters.count)")
// 打印输出 "the number of characters in café is 4"
9 使用startIndex属性可以获取一个String的第一个Character的索引。使用endIndex属性可以获取最后一个Character的后一个位置的索引。因此,endIndex属性不能作为一个字符串的有效下标。如果String是空串,startIndex和endIndex是相等的。
10 Unicode String的等与不等
如果两个字符串(或者两个字符)的可扩展的字形群集是标准相等的,那就认为它们是相等的。在这个情况下,即使可扩展的字形群集是有不同的 Unicode 标量构成的,只要它们有同样的语言意义和外观,就认为它们标准相等。可以用 == 或 != 来比较
11 默认参数可以是一个方法里的任意一个
func someFunction(parameterWithoutDefault: Int, parameterWithDefault: Int = 12, parameThree: Int) {
}
someFunction(parameterWithoutDefault: 4, parameThree: 1)
12 一个函数最多只能拥有一个可变参数, 参数位置在哪为所谓
13 闭包表达式的参数可以是inout参数,但不能设定默认值。也可以使用具名的可变参数(译者注:但是如果可变参数不放在参数列表的最后一位的话
14 逃逸闭包(Escaping Closures)
当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。当你定义接受闭包作为参数的函数时,你可以在参数名之前标注 @escaping,用来指明这个闭包是允许“逃逸”出这个函数的。一种能使闭包“逃逸”出函数的方法是,将这个闭包保存在一个函数外部定义的变量中。举个例子,很多启动异步操作的函数接受一个闭包参数作为 completion handler。这类函数会在异步操作开始之后立刻返回,但是闭包直到异步操作结束后才会被调用。在这种情况下,闭包需要“逃逸”出函数,因为闭包需要在函数返回之后被调用.将一个闭包标记为 @escaping 意味着你必须在闭包中显式地引用 self.
var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
completionHandlers.append(completionHandler)
}
func someFunctionWithNonescapingClosure(closure: () -> Void) {
closure()
}
class SomeClass {
var x = 10
func doSomething() {
someFunctionWithEscapingClosure { self.x = 100 }
someFunctionWithNonescapingClosure { x = 200 }
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
// 打印出 "200"
completionHandlers.first?()
print(instance.x)
// 打印出 "100"
15 @autoclosure
对闭包参数的一种修饰。表明该闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。因此在调用该函数传值时就只需要传以前的闭包中的表达式而非整个表达式闭包。
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(_ customerProvider: @autoclosure @escaping () -> String) {
customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.remove(at: 0))
collectCustomerProviders(customersInLine.remove(at: 0))
print("Collected \(customerProviders.count) closures.")
// 打印出 "Collected 2 closures."
for customerProvider in customerProviders {
print("Now serving \(customerProvider())!")
}
// 打印出 "Now serving Barry!"
// 打印出 "Now serving Daniella!"
16 在使用原始值为整数或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值,Swift 将会自动为你赋值。当使用整数作为原始值时,隐式赋值的值依次递增1。如果第一个枚举成员没有设置原始值,其原始值将为0。当使用字符串作为枚举类型的原始值时,每个枚举成员的隐式原始值为该枚举成员的名称。
17 递归枚举
递归枚举(recursive enumeration)是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上indirect来表示该成员可递归。
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
//或者统一写到外面 indirect
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
func evaluate(_ expression: ArithmeticExpression) -> Int {
switch expression {
case let .number(value):
return value
case let .addition(left, right):
return evaluate(left) + evaluate(right)
case let .multiplication(left, right):
return evaluate(left) * evaluate(right)
}
}
print(evaluate(product))
// 输出 "18"
18 文档注释说明
/// 求和
/// - parameter 参数1: 参数1说明
/// - returns: 返回值
未完待续 欢迎点击爱心