求助 是不是swift 高阶函数1.2版本不支持同名函数了

一、可选型
为什么会有可选型?当一个变量被希望表示为某一个指定的类型值,同时也被希望在某种情况下表示为空。那么就需要一个可选型。Optional
可选型的语法是在Swift的基本类型后面添加 ? 符号,如 Int? String? &可选型如果取值为空,那么表示为 nil
如果想定义一个可选型的变量,那么需要显示的声明为可选型。可选型变量打印时显示Optional
可选型变量需要进行解包(unwrap)才能与其他的变量进行运算。
1. 强制解包,使用 ! 关键字,强制解包是具有风险的,当可选型变量的值为nil时,会报致命错误fatal error
2. 在条件判断语句中进行解包,定义一个新的变量并且将可选型变量赋值给它。如 if let op1 = op1{ } & &if var op1 = op1{}
& & 但是这样定义的新变量仅仅只在if语句块中有效。其他地方无效并没有这个变量。
1 var errorCode: Int? = 404;
2 var errorMsg: String? = "not found";
3 if var errorCode = errorCode,
var errorMsg = errorMsg{
print(errorMsg);
swift3.0版本中,if语句里的条件判断语句不能使用where关键字,而是使用逗号 , 来将多个条件进行分割,同时使用, 逗号保证了所有的条件之间是一种逻辑与 & 的关系
3. optional chaining
使用语法 ? 来尝试解包,可以省略掉大段的 if 语句代码
1 var str: String? = "Swift Optional";
2 str?.uppercased()
1 var msg1 = errorMsg==nil ?"NO Error":errorM
2 var msg2 = errorMsg ?? "No Error";
??也可以用来对可选型变量进行解包 Nil-Coalesce
** 可选型是一个重要的类型
很多方法都会返回可选型类型的结果,如 &Int的构造函数, StringObj.range(of: str)
返回Range&String.Index&?
*** 隐式可选型
语法 var str: String! =
var str: String! = "Hello, Swift";
在类的定义中运用广泛,以后讨论。
数组的类型声明有两种形式:
[Int]方括号里面存放的是数组中数据的类型
Array&Int& 泛型的写法,这种写法和C#中的泛型是一样的,&&中存放的就是数组中数据的类型
所以由此可见,swift中的数组里的每一个成员的数据类型必须一致,并且数组的语法格式和大多数语言一样,都是使用[ ]一对中括号将数据包裹起来。
1 var numbers1:[Int] = [1,2,3,4,5];
2 var numbers2:Array&Int& = [10,11,12,13,14];
3 var letters1:[String] = ["a", "b", "c", "d", "e" ];
4 var letters2:Array&Character& =["x", "y", "z"];
定义空数组: []直接定义空数组,但是必须要求显示声明数组类型; & 使用数组的构造函数进行空数组的声明,此时可以不用显示声明数据类型。
1 var empty1: [Int] = [];
2 var empty2: Array&String& = [];
3 var empty3: [Float] = [Float]();
4 var empty4: [(Int,Int)] = [(Int,Int)]();
5 var empty5: [(Int,Int?)] = Array&(Int,Int?)&();
6 var empty6: [(Int,Int?)?] = Array&(Int,Int?)?&();
数组的一种初始化构造函数:通过给定的长度和一个数据来创建一个具有给定长度的重复值的数组,此时可以不用显示声明数组类型。
1 var arr1 = Array(repeating: "4.5", count: 5);
** 数组的常用成员属性和方法
isEmpty &count &first &last & contains() &index(of: ) &index(after: ) &index(before: ) &startIndex & endIndex & max() &min()
*** 数组的比较
在Swift语言中,数组是一个有序的数据集合。同时数组的比较是值比较,而不是引用比较。
****** 数组的遍历
1 //第一种遍历,将索引值进行循环
2 var arr = [1,2,3,4,5];
3 for index in 0..&arr.count{
arr[index];
7 //第二种遍历,将数组值进行循环
8 for number in arr{
11 //第三种遍历,通过可枚举接口方法获取一个可枚举的结构体
12 for (index, number) in arr.enumerated(){
以上都是数组的查(查找),接着我们来学习 增(增加), 删(删除), 改(修改)
数组方法: += 这里需要注意类型一致,数组只能和数组相加 &append &insert
1 var cousre = ["JavaScript","NodeJS","Vue"];
2 cousre.append("CSS3");
3 course.append(contentsOf: ["HTML","CSS"]);
1 course.insert("JavaScript", at: 4);
2 course.insert(contentsOf: ["CSS3","NodeJS"], at: 2);
数组方法: remove &removeAll removeLast &removeFirst &removeSubrange
remove方法需要指定删除项的索引值
removeLast和removeFirst如果传入索引值参数,表示从开头或者从末尾处开始,指定索引处往后或者往前的内容都会被删除。
修改数组,可以直接使用索引方括号的形式进行修改数据值即可。
***** 二维数组
类型定义 Array&Array&Int&& &[ [Int] ] &Array&[Int]& &[Array&Int&]
二维数组的方法与一维数组是一致的,同样 += 需要注意二维数组只能与二维数组进行相加运算。
提到Swift数组,就不能不提到NSArray。 在Swift3.0版本中,不指定类型的数组默认情况下已经都是Array类型了,不同于2.0版本还在使用NSArray默认类型。
那么如果需要使用NSArray,就必须显示声明NSArray类型,或者 as NSArray语法。
NSArray不同于Array的区别在于NSArray可以将不同类型的数据放到一个数组中。
在Swift3.0版本中,要么使用显示声明为NSArray,要么使用显示声明为NSObject,要么不声明而是将数组中的每一个值as NSObject转换为NSObject类型
三、Dictionary字典
字典是一组键值对的无序集合,所以字典的比较也是值比较,但是注意是无序的。同时字典的键名是具有唯一性的。
字典的类型声明 Dictionary&String, String& &[String : String]
空字典的声明 [:] &Dictionary&String, String&() &[String: String]()
dic.keys & dic.values &都是LazyMapCollection&Dictionary&String,String&,String&
dic.count & dic.isEmpty
1 var edic1:[String:String] = [:];
2 var edic2:Dictionary&String,String& = [:];
3 var edic3 = [String:String]();
4 var edic4 = Dictionary&String,String&();
1 Array(dic.keys);
2 Array(dic.values);
3 //字典的遍历
4 //键名的遍历
5 for key in dic.keys{
print(key);
8 //键值的遍历
9 for value in dic.values{
print(value);
12 //键值对的遍历
13 for (key,value) in dic{
print(key);
print(value);
字典的增删改查方法: 使用键名的方式来增加,修改或删除某个值 & updateValue(value, forKey: key); & &removeAll(); & removeValue(forKey: key);
四、集合Set
集合Set的类型声明: Set&Int&
1 var set : Set&Int& = [1,2,6,4,3,5,8];
2 var empty1 = Set&Int&();3 var empty2: Set&String& = [];
4 var empty3: Set&Int& = Set();
属性与方法: count & &isEmpty & first &contains() &removeAll() &remove() &removeFirst()
***** for in语句可以遍历 Range, Characters, Array, Dictionary, Set.
可以发现,凡是符合一个序列特性的类型值都是可以使用for in语句进行循环遍历,String类型就不符合序列Sequence所以不能使用for in.
函数的定义语法,以func关键字开头, 返回值使用 -& 形式表示。如果函数没有返回值,可以不写 -& ,也可以写成 -& () 或者 &-& Void
1 //函数定义语法
2 //func funcName(arg1: type, arg2 : type, ...) -& type {
return .....;
6 func sayHelloTo(name: String?) -& String{
return "Say Hello to " + (name?.uppercased() ?? "Guest" );
10 sayHelloTo(name : "Jordan mike");
函数的返回值是元组类型时,可以返回多个返回值
1 func findMaxAndMin(numbers: Array&Int&)-&(max: Int, min: Int)?{
guard numbers.count & 0 else {
var minNumber = numbers[0];
var maxNumber = numbers[0];
for number in numbers{
maxNumber = number & maxNumber ? number : maxN
minNumber = number & minNumber ? number : minN
return (maxNumber, minNumber);
swift语言中的 &外部参数名,内部参数名,调用时省略参数名
默认情况下,内部和外部参数名是一致的。
如果需要指定外部参数名,可以在参数名前面再添加一个参数名。这样前面的是外部参数名,后面的是内部参数名。
如果需要省略调用函数时的外部参数名,需要将外部参数名定义为下划线 _
1 func speakTo(name: String, words: String)-&String{
return name + "Speak some words: " +
5 speakTo(name: "tom", words: "I love you");
7 func speak(to name: String, letters words: String)-&String{
return name + "Speak some words: " +
11 speak(to: "nike", letters: "I love football");
13 func say(_ name: String, _ words: String)-&String{
return name + "Speak some words: " +
17 say("andi", "I love you! ");
定义函数时,可以给函数中的参数定义默认值,这样在调用函数时可以省掉该参数,从而采用默认值进行函数调用。
定义函数时,可以给函数定义可变参数,语法是在参数类型后面加上 ... 但是在一个函数中最多只能有一个可变参数。与其他语言不同的是,swift语言并没有强制要求可变参数的位置必须是最后一个参数。
在Swift3.0版本中,函数参数前面关键字只能使用默认的let 以及 inout引用类型参数,默认情况下函数的形参都是值传入方式,同时在函数内部是不允许对该参数进行重新赋值计算的。在swift2.0版本中定义了var 关键字,但是在3.0版本中却将这个语法取消了。兼容方式是在函数内部重新定义一个同名的var变量。 如果你希望函数调用时使用引用传递的方式,那么需要在该形参冒号后面,也就是参数类型前面添加关键字 inout ,同时在函数调用时使用&语法。 可以通过swap函数进行理解。
函数类型也是一种变量类型,可以用来实现所谓的委托。参考Array的sort, sorted, map, filter, reduce等方法。这里需要注意的是swift2.0版本中的sort与sortInPlace在新版中已经被修改了。
****函数闭包 closure
1 //Trailing closure
2 var arr = [1,11,22,12,32,31,18];
3 arr.sort(by: {(a:Int, b:Int)-&Bool in return a&b;});
4 arr.sort(by: {a,b in return a&b;});
5 arr.sort(by: {a,b in a&b;});
6 arr.sort(by: {$0&$1;});
7 arr.sort(by: &);
***** &闭包和函数都是引用类型,而基本类型数组集合字典都是值类型
阅读(...) 评论()Swift 文档修订历史
翻译+校对:
翻译+校对:
翻译+校对:
翻译+校对:,
翻译+校对:,
本页面根据
进行适配更新。
本页内容包括:
Swift 3.1 更新
语法变更记录
更新至 Swift 3.0.1。
更新章节中关于 weak 和 unowned 引用的讨论。
增加章节中关于新的标识符`unowned`,`unowend(safe)`和`unowned(unsafe)`的描述。
增加一节中关于使用类型`Any`作为可选值的描述。
更新章节,把括号表达式和元组表达式的描述分开。
Swift 3.0 更新
语法变更记录
更新至 Swift 3.0。
更新章节中关于函数的讨论,在一节中,标明所有函数参数默认都有函数标签。
更新章节中关于操作符的讨论,现在你可以作为类型函数来实现,替代之前的全局函数实现方式。
增加章节中关于对新的访问级别描述符open和fileprivate的信息
更新一节中关于inout的讨论,标明它放在参数类型的前面,替代之前放在参数名称前面的方式。
更新和还有章节中关于@noescape和@autoclosure的讨论,现在他们是类型属性,而不是定义属性。
增加章节中一节和章节中一节中关于操作符优先级组的信息。
更新一些讨论:使用 macOS 替换掉 OS X, Error 替换掉 ErrorProtocol,和更新一些协议名称,比如使用 ExpressibleByStringLiteral 替换掉 StringLiteralConvertible。
更新章节中一节和章节,现在泛型的 where 语句写在一个声明的最后。
更新一节,现在闭包默认为非逃逸的(noescaping)。
更新章节中一节和章节中一节,现在 if,while 和 guard 语句使用逗号分隔条件列表,不需要使用 where 语句。
增加章节中一节和章节中一节关于 switch cases 可以使用多模式的信息。
更新一节,现在函数参数标签不包含在函数类型中。
更新章节中一节和章节中一节关于使用新的 Protocol1 & Protocol2 语法的信息。
更新一节使用新的 type(of:) 表达式的信息。
更新一节使用 #sourceLocation(file:line:) 表达式的信息。
更新一节使用 新的 Never 类型的信息。
增加一节关于 playground 字面量的信息。
更新一节,标明只有非逃逸闭包能捕获 in-out 参数。
更新一节,现在默认参数不能在调用时候重新排序。
更新章节中关于属性参数使用分号的说明。
增加一节中关于在 catch 代码块中抛出错误的重新抛出函数的信息。
增加一节中关于访问 Objective-C 中 Selector 的 getter 和 setter 的信息。
增加一节,标明函数类型作为参数类型必须使用括号包裹。
增加一节中关于泛型类型别名和在协议内使用类型别名的信息。
更新章节,标明 @IBAction,@IBOutlet 和 @NSManaged 隐式含有 @objc 属性。
增加一节中关于 @GKInspectable 的信息。
更新一节中关于只能在与 Objective-C 交互的代码中才能使用可选协议要求的信息。
删除一节中关于显式使用 let 关键字作为函数参数的信息。
删除一节中关于 Boolean 协议的信息, 现在这个协议已经被 Swift 标准库删除。
更正一节中关于 @NSApplicationMain 协议的信息。
Swift 2.2 更新
语法变更记录
更新至 Swift 2.2。
增加了一节中关于如何根据 Swift 版本进行条件编译。
增加了一节中关于如何区分只有参数名不同的方法和构造器的信息。
增加了一节中针对 Objective-C 选择器的 #selector 语法。
更新了和声明,使用 associatedtype 关键词修改了对于关联类型的讨论。
更新了一节中关于当构造器在实例完全初始化之前返回 nil的相关信息。
增加了一节中关于比较元组的信息。
增加了一节中关于使用关键字作为外部参数名的信息。
增加了一节中关于@objc特性的讨论,并指出枚举(Enumeration)和枚举用例(Enumaration Case)。
增加了一节中对于自定义运算符的讨论包含了.。
增加了一节中关于重新抛出错误函数不能直接抛出错误的笔记。
增加了一节中关于当作为 in-out 参数传递属性时,属性观察器的调用行为。
增加了一节中关于错误处理的内容。
更新了一节中的图片用以更清楚的展示重新分配过程。
删除了 C 语言风格的 for 循环,++ 前缀和后缀运算符,以及-- 前缀和后缀运算符。
删除了对变量函数参数和柯里化函数的特殊语法的讨论。
Swift 2.1 更新
语法变更记录
更新至 Swift 2.1。
更新了和小节,现在字符串插值可包含字符串字面量。
增加了在一节中关于 @noescape 属性的相关内容。
更新了和小节中与 tvOS 相关的信息。
增加了 小节中与
in-out 参数行为相关的信息。
增加了在一节中关于指定闭包捕获列表被捕获时捕获值的相关内容。
更新了通过一节,阐明了如何通过可选链式调用进行赋值。
改进了一节中对自闭包的讨论。
在一节中更新了一个使用??操作符的例子。
Swift 2.0 更新
语法变更记录
更新至 Swift 2.0。
增加了对于错误处理相关内容,包括 一章、、、以及 的多个小节。
更新了一节,现在所有类型均可遵循 ErrorType 协议。
增加了一节 try? 关键字的相关信息。
增加了一章的一节和一章的一节中关于递归枚举的内容。
增加了一章中a href="/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ControlFlow.html#//apple_ref/doc/uid/TP-CH9-ID523"&检查 API 可用性一节和一章中一节中关于 API 可用性检查的内容。
增加了一章的一节和一章的中关于新 guard 语句的内容。
增加了一章中一节中关于协议扩展的内容。
增加了一章中一节中关于单元测试的访问控制相关的内容。
增加了一章中一节中的新可选模式。
一节中关于repeat-while循环的信息。
更新了一章,现在String在 Swift 标准库中不再遵循CollectionType协议。
增加了一节中关于新 Swift 标准库中关于 print(_:separator:terminator) 的信息。
增加了一章中一节和一章的一节中关于包含String原始值的枚举用例的行为。
增加了一节中关于@autoclosure特性的相关信息,包括它的@autoclosure(escaping)形式。
更新了一节中关于@avaliable和warn_unused_result特性的相关内容。
更新了一节中关于@convention特性的相关信息。
增加了一节中关于使用where子句进行多可选绑定的内容。
增加了一节中关于在编译时使用 + 运算符凭借字符串字面量的相关信息。
增加了一节中关于元类型值的比较和使用它们通过构造器表达式构造实例。
增加了一节中关于用户定义断言是被警用的相关内容。
更新了一节中,对@NSManaged特性的讨论,现在这个特性可以被应用到一个确定实例方法。
更新了一节,现在可变参数可以声明在函数参数列表的任意位置中。
增加了一节中,关于非可失败构造器相当于一个可失败构造器通过父类构造器的结果进行强制拆包的相关内容。
增加了一节中关于枚举用例作为函数的内容。
增加了一节中关于显式引用一个构造器的内容。
更新了一节中关于编译信息以及行控制语句的相关信息。
更新了一节中关于如何从元类型值中构造类实例。
更新了一节中关于弱引用作为缓存的显存的不足。
更新了一节,提到了存储型特性其实是懒加载。
更新了一节,阐明了变量和常量在闭包中如何被捕获。
更新了一节用以描述如何在类中使用@objc关键字。
增加了一节中关于执行throw语句的性能的讨论。增加了 Do 语句一节中相似的信息。
更新了一节中关于类、结构体和枚举的存储型和计算型特性的信息。
更新了一节中关于带标签的 break 语句。
更新了一节,阐明了willSet和didSet观察器的行为。
增加了一节中关于private作用域访问的相关信息。
增加了一节中关于若应用在垃圾回收系统和 ARC 之间的区别。
更新了一节中对 Unicode 标量更精确的定义。
Swift 1.2 更新
语法变更记录
更新至 Swift 1.2。
Swift现在自身提供了一个Set集合类型,更多信息请看
@autoclosure现在是一个参数声明的属性,而不是参数类型的属性。这里还有一个新的参数声明属性@noescape。更多信息,请看
对于类型属性和方法现在可以使用static关键字作为声明描述符,更多信息,请看
Swift现在包含一个as?和as!的向下可失败类型转换运算符。更多信息,请看
增加了一个新的指导章节,它是关于的
从中移除了溢出除运算符(&/)和求余溢出运算符(&%)。
更新了常量和常量属性在声明和构造时的规则,更多信息,请看
更新了字符串字面量中Unicode标量集的定义,请看
更新了章节来提示当半开区间运算符含有相同的起止索引时,其区间为空。
更新了章节来澄清对于变量的捕获规则
更新了章节来澄清有符号整数和无符号整数的溢出行为
更新了章节来澄清协议声明时的作用域和成员
更新了章节来澄清对于闭包捕获列表中的弱引用和无主引用的使用语法。
更新了章节来明确指明一些例子来说明自定义运算符所支持的特性,如数学运算符,各种符号,Unicode符号块等
在函数作用域中的常量声明时可以不被初始化,它必须在第一次使用前被赋值。更多的信息,请看
在构造器中,常量属性有且仅能被赋值一次。更多信息,请看
多个可选绑定现在可以在if语句后面以逗号分隔的赋值列表的方式出现,更多信息,请看
一个必须出现在后缀表达式中
协议类型转换不再局限于@obj修饰的协议了
在运行时可能会失败的类型转换可以使用as?和as!运算符,而确保不会失败的类型转换现在使用as运算符。更多信息,请看
Swift 1.1 更新
语法变更记录
更新至 Swift 1.1。
增加了关于的完整章节。
增加了协议中关于失败构造器要求的描述。
常量和变量的 Any 类型现可以包含函数实例。更新了关于 Any 相关的示例来展示如何在 switch 语句中如何检查并转换到一个函数类型。
带有原始值的枚举类型增加了一个rawValue属性替代toRaw()方法,同时使用了一个以rawValue为参数的失败构造器来替代fromRaw()方法。更多的信息,请看和部分。
自定义运算符现在可以包含`?`字符,更新的章节描述了改进后的规则,并且从章节删除了重复的运算符有效字符集合
Swift 1.0 更新
语法变更记录
发布新的文档用以详述 Swift 1.0,苹果公司针对iOS和OS X应用的全新开发语言。
在章节协议中,增加新的小节:
在章节协议中,增加新的小节:
现在可以使用字符串内插语法,并删除了文档中有冲突的注释
更新了小节来说明一个事实,那就是字符串和字符不能再用+号运算符或者复合加法运算符+=相互连接,这两种运算符现在只能用于字符串之间相连。请使用String类型的append方法在一个字符串的尾部增加单个字符
在章节增加了关于availability特性的一些信息
若有值时,不再隐式的转换为 true,同样,若无值时,也不再隐式的转换为 false, 这是为了避免在判别 optional Bool 的值时产生困惑。 替代的方案是,用== 或 != 运算符显式地去判断Optinal是否是 nil,以确认其是否包含值。
Swift新增了一个
(a ?? b), 该表达式中,如果Optional a的值存在,则取得它并返回,若Optional a为nil,则返回默认值 b
更新和扩展
章节,用以反映和展示'字符串和字符的比较',以及'前缀(prefix)/后缀(postfix)比较'都开始基于扩展字符集(extended grapheme clusters)规范的等价比较.
现在,你可以通过 来:给属性设值,将其赋给一个下标脚注(subscript); 或调用一个变异(mutating)方法或运算符。对此,章节——的内容已经被相应的更新。而章节——中,关于检查方法调用是否成功的例子,已被扩展为展示如何检查一个属性是否被设值成功。
在章节可选链中,增加一个新的小节
以标示:从该版本起,不能再通过+= 运算符给一个数组添加一个新的项。. 对应的替代方案是, 使append 方法, 或者通过+=运算符来添加一个只有一个项的数组(single-item Array).
添加了一个提示:在 中,比如, a...b 和 a..&b ,起始值a不能大于结束值b.
重写了 这一章:删除了本章中关于构造器重写的介绍性报道;转而将更多的注意力放到新增的部分——子类的新功能,以及如何通过重写(overrides)修改已有的功能。另外,小节
中的例子已经被替换为展示如何重写一个 description 属性. (而关于如何在子类的构造器中修改继承属性的默认值的例子,已经被移到
小节以标示: 重写一个特定的构造器必须使用 override 修饰符.
小节以标示:required 修饰符现在需要出现在所有子类的required构造器的声明中, 而required构造器的实现,现在可以仅从父类自动继承。
中置(Infix)的
不再需要@infix 属性.
的@prefix 和 @postfix 属性,已变更为 prefix 和 postfix 声明修饰符(declaration modifiers).
增加一条注解:当Prefix和postfix运算符被作用于同一个操作数时,关于的顺序(postfix运算符会先被执行)
在运算符函数(Operator functions)中,
不再使用 @assignment 属性来定义函数.
在这个版本中,在定义 时,修饰符(Modifiers)的出现顺序发生变化。比如, 现在,你该编写 prefix operator, 而不是 operator prefix.
增加信息:关于dynamic 声明修饰符(declaration modifier),于章节 .
增加信息: 的类型推导(type inference)
为章节添加了更多的信息.
加入新的章节
更新了章节
用以表明,在Swift中,Character 类型现在代表的是扩展字符集(extended grapheme cluster)中的一个Unicode,为此,新增了小节
。同时,为小节
和 增加了更多内容.
更新章节:在一个字符串中,Unicode标量(Unicode scalars) 以 \u{n}的形式来表示, n 是一个最大可以有8位的16进制数(hexadecimal digits)
NSString length 属性已被映射到Swift的内建 String类型。(注意,这两属性的类型是utf16Count,而非 utf16count).
Swift的内建 String 类型不再拥有 uppercaseString 和 lowercaseString 属性.其对应部分在章节 已经被删除, 并且各种对应的代码用例也已被更新.
加入新的章节
加入新的章节
加入新的章节 .
:多个相关变量可以用“类型标注”(type annotaion)在同一行中声明为同一类型。
@optional, @lazy, @final,
@required 等关键字被更新为 optional, lazy, final, required .
更新整本书 —— 引用 ..& 作为 (取代原先的.. ).
更新了小节 :
Dictionary 现在早呢更加了一个 Boolean型的属性: isEmpty
解释了哪些字符(集)可被用来定义
nil 和布尔运算中的 true 和 false 现在被定义为字面量.
Swift 中的数组 (Array) 类型从现在起具备了完整的值语义。具体信息被更新到
两小节,以反映这个新的变化. 此外,还解释了如何 .
从 SomeType[].更新为[SomeType]
加入新的小节:.: [KeyType: ValueType].
加入新的小节:.
中使用新的全局函数 sorted 取代原先的全局函数 sort 去展示如何返回一个全新的数组.
的描述:即使结构体的成员没有默认值,逐一成员构造器也可以自动获得。
由..更新到..&
添加一个例子1.Swift基本语法_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
1.Swift基本语法
上传于|0|0|文档简介
&&Swift语言学习
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩17页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢[精校版]The Swift Programming Language--属性--函数
我的图书馆
[精校版]The Swift Programming Language--属性--函数
Swift系列文章由CocoaChina翻译小组翻译自苹果的官方文档:。本篇译者:Da杯柠檬水(),敬请勘误,欢迎在参看更多文章。
函数是执行特定任务的代码自包含块。通过给定一个函数名称标识它是什么,并在需要的时候使用该名称来调用函数以执行任务。
Swift的统一的功能语法足够灵活的,可表达任何东西,无论是不带参数名称的简单的样式函数,还是带本地和外部参数名称的复杂的Objective-C样式方法。参数可为简单函数调用提供默认值,并且可以被作为输入/输出参数传递,在函数执行完成时修改传递来的变量。
Swift中的每个函数都有一个类型,包括函数的参数类型和返回类型。你可以像使用Swift中其他类型一样使用该类型,这使得它很容易将函数作为参数传递给其他函数,甚至从函数中返回函数类型。函数也可以被写入其他函数中以在函数作用于中封装有用的功能。
定义和调用函数
当你定义一个函数时,你可以选择性地定义一个或多个名称,类型值作为函数的输入(称为形参),或者定义一个函数结束后返回值的类型(称之为返回型)。每一个函数都有一个函数名,用来描述了函数执行的任务。要使用一个函数时,可使用它的名称进行“调用”,并通过它的输入值(称为实参--argument)来匹配函数的参数类型。一个函数的实参(arguments)必须始终和函数形参(parameter)顺序一致。
例如在下面的例子中被调用的函数greetingForPerson,像它描述的那样 -- 它需要一个人的名字作为输入并返回一句针对那个人的问候语。为了实现该功能,你定义了一个输出参数--一个名为personName的字符串值,以及一个String返回类型,包含一个针对那个人的问候语:
func&sayHello(personName:&String)&-&&String&{&&&&&let&greeting&=&"Hello,&"&+&personName&+&"!"&&&&&return&greeting&}&
所有这些信息都汇总到以func关键字为前缀的函数定义中。使用箭头-&来指明函数的返回类型(一个连字符后跟一个向右的箭头),后边跟着返回的类型名称。
该定义描述了函数的作用是什么,它期望接收什么,以及完成后返回的结果。该定义可轻易地让你在代码中的其他地方清晰明确地调用该函数:
println(sayHello("Anna"))&//&prints&"Hello,&Anna!"&println(sayHello("Brian"))&//&prints&"Hello,&Brian!"&
你可以通过给它传递一个圆括号内String实参值来调用sayHello函数,例如sayHello("Anna")。由于该函数返回一个String值,sayHello可以被包裹在一个println函数调用中来打印字符串,看看它的返回值,如上图所示。
sayHello的函数主体首先定义了一个新的名为greeting的String常量,并将其设置加上personName组成一句简单的问候消息。然后这个greeting以关键字return来传回到函数外部。只要return greeting被调用,函数执行完毕后就会返回greeting的当前值。
你可以通过不同的输入值多次调用sayHello的函数。上面的例子显示了如果使用"Anna"输入值调用它会发生什么,以及以"Brian"输入值调用时会发生什么。函数为每种情况量身定制了问候语。
为了简化这个函数的主体,可把消息创建和return语句合并成一行:
func&sayHello(personName:&String)&-&&String&{&&&&&return&"Hello&again,&"&+&personName&+&"!"&}&println(sayHello("Anna"))&//&prints&"Hello&again,&Anna!"&
函数的形参和返回值
在swift中,函数的形参和返回值是非常具有灵活性的。你可以定义任何事情,无论是一个简单的仅有一个未命名形参的工具函数,还是那种具有丰富的参数名称和不同的形参选项的复杂函数。
多输入形参
函数可以有多个输入形参,把它们写到函数的括号内,并用逗号加以分隔。下面这个函数设置了一个半开区间的开始和结束索引,用来计算在范围内有多少元素:
func&halfOpenRangeLength(start:&Int,&end:&Int)&-&&Int&{&&&&&return&end&-&start&}&println(halfOpenRangeLength(1,&10))&//&prints&"9"&
无形参函数
函数并没有要求一定要定义的输入形参。下面就是一个没有输入形参的函数,任何时候调用时它总是返回相同的String消息:
func&sayHelloWorld()&-&&String&{&&&&&return&"hello,&world"&}&println(sayHelloWorld())&//&prints&"hello,&world"&
该函数的定义还需要在函数的名称后跟一对儿圆括号,即使它不带任何形参。当函数被调用时函数名称也要跟着一对儿空括号。
无返回值的函数
函数不需要定义一个返回类型。这里有一个版本的sayHello函数,称为waveGoodbye,它会打印自己的String值而不是返回它:
func&sayGoodbye(personName:&String)&{&&&&&println("Goodbye,&\(personName)!")&}&sayGoodbye("Dave")&//&prints&"Goodbye,&Dave!"&
&因为它并不需要返回一个值,该函数的定义不包括返回箭头( - &)和返回类型。
&&提示:严格地说,sayGoodbye函数确实还返回一个值,即使没有定义返回值。没有定义返回类型的函数返回了一个Void类型的特殊值。这仅是一个空元组,这里边没有元素,可以被写成()。
当一个函数调用时它的返回值可以忽略不计:
func&printAndCount(stringToPrint:&String)&-&&Int&{&&&&&println(stringToPrint)&&&&&return&countElements(stringToPrint)&}&func&printWithoutCounting(stringToPrint:&String)&{&&&&&printAndCount(stringToPrint)&}&printAndCount("hello,&world")&//&prints&"hello,&world"&and&returns&a&value&of&12&printWithoutCounting("hello,&world")&//&prints&"hello,&world"&but&does&not&return&a&value&
&第一个函数printAndCount,打印了一个字符串,然后并以Int类型返回它的字符数。第二个函数printWithoutCounting,调用的第一个函数,但忽略它的返回值。当第二函数被调用时,消息由第一函数打印了回来,但没有使用其返回值。
&提示:返回值可以忽略,但一个定义了返回值的函数则必须有返回值。对于一个定义了返回类型的函数来说,如果没有返回值,那么将不允许控制流离开函数的底部。如果试图这样做将出现一个编译时错误。
多返回值函数
你可以使用一个元组类型作为函数的返回类型,来返回一个由多个值组成的复合返回值。
下面的例子定义了一个名为count函数,用来计算字符串中基于标准美式英语的元音、辅音以及字符的数量:
func&count(string:&String)&-&&(vowels:&Int,&consonants:&Int,&others:&Int)&{&&&&&var&vowels&=&0,&consonants&=&0,&others&=&0&&&&&for&character&in&string&{&&&&&&&&&switch&String(character).lowercaseString&{&&&&&&&&&case&"a",&"e",&"i",&"o",&"u":&&&&&&&&&&&&&++vowels&&&&&&&&&case&"b",&"c",&"d",&"f",&"g",&"h",&"j",&"k",&"l",&"m",&&&&&&&&&"n",&"p",&"q",&"r",&"s",&"t",&"v",&"w",&"x",&"y",&"z":&&&&&&&&&++consonants&&&&&&&&&default:&&&&&&&&&++others&&&&&&&&&}&&&&&}&&&&&return&(vowels,&consonants,&others)&}&
您可以使用此计数函数来对任意字符串进行字符计数,以检索一个包含三个指定Int值的元素统计总数:
let&total&=&count("some&arbitrary&string!")&println("\(total.vowels)&vowels&and&\(total.consonants)&consonants")&//&prints&"6&vowels&and&13&consonants"&
注意:这一点上元组的成员不需要被命名,元组是从函数中返回的,因为它们的名字已经被指定为函数的返回类型的一部分。
函数形参名
所有上面的函数都为其形参定义了形参名:
func&someFunction(parameterName:&Int)&{&&&&&//&function&body&goes&here,&and&can&use&parameterName&&&&&//&to&refer&to&the&argument&value&for&that&parameter&}&
然而,这些参数名的仅能在函数本身的主体内使用,不能在调用函数时使用。这种形参类型名称被称之为本地形参名(local parameter name),因为它们只能在函数的主体中使用。
外部形参名
有时当你调用一个函数将每个形参进行命名是非常有用的,以表明你把每个实参传递给函数的目的。
如果你希望使用你函数的人在调用函数时提供形参名称,那除了本地形参名外,你还要为每个形参定义一个外部形参名称。你写一个外部形参名称在它所支持的本地形参名称之前,之间用一个空格来分隔:
func&someFunction(externalParameterName&localParameterName:&Int)&{&&&&&//&function&body&goes&here,&and&can&use&localParameterName&&&&&//&to&refer&to&the&argument&value&for&that&parameter&}&
&&提示:如果您为形参提供一个外部形参名称,那么外部形参名必须在调用时使用。
举一个例子,考虑下面的函数,通过在它们之间插入第三个"joiner"字符串来连接两个字符串:
func&join(s1:&String,&s2:&String,&joiner:&String)&-&&String&{&&&&&return&s1&+&joiner&+&s2&}&
当你调用这个函数,你传递给函数的三个字符串的目的就不是很清楚了:
join("hello",&"world",&",&")&//&returns&"hello,&world"&
为了使这些字符串值的目的更为清晰,为每个join函数形参定义外部形参名称:
func&join(string&s1:&String,&toString&s2:&String,&withJoiner&joiner:&String)&&&&&-&&String&{&&&&&return&s1&+&joiner&+&s2&}&
在这个版本的join函数中,第一个形参的外部名称string,本地名称s1;第二个形参的外部名称toString,本地名称s2;第三个形参的外部名称是withJoiner,本地名称为joiner。
现在,您可以使用这些外部形参名称清楚明确地调用该函数:
join(string:&"hello",&toString:&"world",&withJoiner:&",&")&//&returns&"hello,&world"&
&使用外部参数名称使join函数的第二个版本功能以更富有表现力,用户习惯的sentence-like方式调用函数,同时还提供了一个可读的、意图明确的函数体。
&&注意:在别人第一次阅读你的代码不知道你函数形参目的时候,就要考虑到使用外部形参名称了。在调用函数的时候,如果每个形参的目的清晰明确的话,那你就无需指定外部形参名。
外部参数名称速记
如果你想为一个函数提供一个外部形参名,然而本地形参名已经使用了一个合适的名称了,那你就不需要两次书写该形参的名称。相反,你可以写一次名字,并用一个hash符号(#)作为名称的前缀。这就告诉Swift使用名称相同的本地行参名称和外部形参名称。
这个例子定义了一个名为containsCharacter的函数,通过在本地形参名前添加hash符号(#)来定义外部形参名称。
func&containsCharacter(#string:&String,&#characterToFind:&Character)&-&&Bool&{&&&&&for&character&in&string&{&&&&&&&&&if&character&==&characterToFind&{&&&&&&&&&&&&&return&true&&&&&&&&&}&&&&&}&&&&&return&false&}&
该函数对形参名的选择使得其函数主题更加清晰易读,并且在调用该函数时也不会有歧义:
let&containsAVee&=&containsCharacter(string:&"aardvark",&characterToFind:&"v")&//&containsAVee&equals&true,&because&"aardvark"&contains&a&"v"&
默认形参值
你可以为任何形参定义默认值以作为函数定义的一部分。如果已经定义了默认值,那么调用函数时就可以省略该行参。
注意:请在函数形参列表的末尾放置带默认值的形参。这将确保所有函数调用都使用顺序相同的无默认值实参,并让在每种情况下清晰地调用相同的函数。
这里有一个早期的join函数,并为参数joiner设置了默认值:
func&join(string&s1:&String,&toString&s2:&String,&&&&&withJoiner&joiner:&String&=&"&")&-&&String&{&&&&&&&&&return&s1&+&joiner&+&s2&}&
如果在join函数调用时为joiner提供了字符串值,那么该字符串值可以用来连接两个字符串,就跟以前一样:
join(string:&"hello",&toString:&"world",&withJoiner:&"-")&//&returns&"hello-world"&
但是,如果函数调用时没有为joiner提供值,就会使用单个空格(" ")的默认值:
join(string:&"hello",&toString:&"world")&//&returns&"hello&world"&
有默认值的外部形参名
在大多数情况下,为所有形参提供一个带默认值的外部名是非常有用的(因此要求)。如果在调用函数的时候提供了一个值,那么这将确保形参对应的实参有着明确的目的。
为了使这个过程更容易,当你自己没有提供外部名称时,Swift将为你定义的任何默认形参提供一个自动外部名。这个自动外部名和本地名一样,就像你已经在本地名前添加了hash符号(#)一样。
这里有一个早期join函数版本,没有为任何外部形参提供外部名,但仍然提供了joiner形参的默认值:
func&join(s1:&String,&s2:&String,&joiner:&String&=&"&")&-&&String&{&&&&&return&s1&+&joiner&+&s2&}&
在这种情况下,Swift为带默认值的形参提供了外部形参名,当调用该函数的时候,外部形参名必须让形参的目的明确无歧义:
join("hello",&"world",&joiner:&"-")&//&returns&"hello-world"&
&注意:在定义形参时,你可以通过使用下划线(_)来代替显示外部名称。不过在适当的情况下,带有默认值形参的外部名通常是优先推荐的。
一个可变形参可接受零个或多个指定类型的值。当函数被调用时,你可以使用可变形参来指定--形参可以用来传递任意数量的输入值。可通过在形参的类型名后边插入三个点符号(...)来编写可变形参。
传递至可变形参的值在函数主体内是以适当类型的数组存在的。例如,一个可变参数的名称为numbers和类型为Double...在函数体内就作为名为numbers类型为Double[]的常量数组。
下边示例为任何长度的数字列表计算算术平均值:
func&arithmeticMean(numbers:&Double...)&-&&Double&{&&&&&var&total:&Double&=&0&&&&&for&number&in&numbers&{&&&&&&&&&total&+=&number&&&&&}&&&&&return&total&/&Double(numbers.count)&}&arithmeticMean(1,&2,&3,&4,&5)&//&returns&3.0,&which&is&the&arithmetic&mean&of&these&five&numbers&arithmeticMean(3,&8,&19)&//&returns&10.0,&which&is&the&arithmetic&mean&of&these&three&numbers&
&注意:函数最多可以有一个可变形参,而且它必须出现在参数列表的最后,以避免使用多个形参调用函数引发歧义。如果你的函数有一个或多个带有默认值的形参,并且还有可变形参,请将可变形参放在所有默认形参之后,也就是的列表的最末尾。
常量形参和变量形参
函数的形参默认是常量。试图在函数体内改变函数形参的值会引发一个编译时错误。这意味着你不能错误地改变形参的值。
但是有时候,函数有一个形参值的变量副本是非常有用的。您可以指定一个或多个形参作为变量形参,从而避免在函数内部为自己定义一个新的变量。变量参数是变量而非常量,并给函数一个可修改的形参值副本。
在参数名称前用关键字var定义变量参数:
func&alignRight(var&string:&String,&count:&Int,&pad:&Character)&-&&String&{&&&&&let&amountToPad&=&count&-&countElements(string)&&&&&for&_&in&1...amountToPad&{&&&&&&&&&string&=&pad&+&string&&&&&}&&&&&return&string&}&let&originalString&=&"hello"&let&paddedString&=&alignRight(originalString,&10,&"-")&//&paddedString&is&equal&to&"-----hello"&//&originalString&is&still&equal&to&"hello"&
这个例子定义了一个新函数叫做alignRight,用于将一个输入字符串和更长的输出字符串右边缘对齐。所有左侧的空白使用指定的占位符来填充。在这个例子中,字符串"hello"被转化为字符串"-----hello"。
alignRight函数把输入的形参字符串定义成一个变量形参。这意味着字符串现在可以作为一个本地变量,用传入的字符串值初始化,并且可以在函数体中进行相应操作。
函数首先要找出有多少字符需要被添加到字符串的左侧,从而在整个字符串中靠右对齐。这个值存储在本地常量amountToPad中。该函数然后将填充字符的amountToPad个字符拷贝到现有的字符串的左边,并返回结果。
&&注意:你对变量形参所做的改变不会比调用函数更持久,并且在函数体外是不可见的。变量形参仅存在于函数调用的声明周期中。
In-Out 形参
如上描述,变量形参只能在函数本身内改变。如果你想让函数改变形参值,并想要在函数调用结束后保持形参值的改变,那你可以把形参定义为in-out形参。
通过在形参定义的开始添加inout关键字来编写in-out形参。In-Out形参有一个传递至函数的值,由函数修改,并从函数返回来替换原来的值。
你只能传递一个变量作为in-out形参对应的实参。你不能传递一个常量或者字面量作为实参,因为常量和字面量不能被修改。当你把变量作为实参传递给in out形参时,需要在直接在变量前添加 & 符号,以表明它可以被函数修改。
提示:in-out参数不能有默认值,可变参数的参数也不能被标记为inout。如果您标记参数为inout,它不能同时被标记为var或let。
这里的一个叫做swapTwoInts函数,它有两个称为a和b的in-out整型形参:
func&swapTwoInts(inout&a:&Int,&inout&b:&Int)&{&&&&&let&temporaryA&=&a&&&&&a&=&b&&&&&b&=&temporaryA&}&
swapTwoInts函数只是简单地交换a、b的值。该函数通过存储一个名为temporaryA临时常量的值,指定b的值到a,然后分配temporaryA到b执行该交换。
你可以通过两个Int类型的变量调用swapTwoInts函数,从而交换它们的值。需要注意的是当它们被传递给swapTwoInts函数时,someInt和anotherInt名称前要加上前缀符号&:
var&someInt&=&3&var&anotherInt&=&107&swapTwoInts(&someInt,&&anotherInt)&println("someInt&is&now&\(someInt),&and&anotherInt&is&now&\(anotherInt)")&//&prints&"someInt&is&now&107,&and&anotherInt&is&now&3"&
上面的例子表明,someInt和anotherInt的原始值由swapTwoInts函数进行了修改,即使它们定义在函数外部。
&注意:In-out形参不同于从函数返回一个值。上边swapTwoInts例子没有定义返回类型或者返回值,但它仍然会修改someInt和anotherInt的值。对函数来说,In-out形参是一个影响函数主体范围外的可选方式。
每一个函数都有特定的函数类型,由函数的形参类型和返回类型组成。例如:
func&addTwoInts(a:&Int,&b:&Int)&-&&Int&{&&&&&return&a&+&b&}&func&multiplyTwoInts(a:&Int,&b:&Int)&-&&Int&{&&&&&return&a&*&b&}&
这个例子中定义了两个简单的数学函数addTwoInts和multiplyTwoInts。每个函数接受两个int值,并返回一个int值,执行适当的数学运算并返回结果。
这两个函数的类型都是(Int, Int)-&Int。可以解读为:"这个函数类型,它有两个Int类型形参,并返回一个Int类型的值。"
下面是另一个例子,该函数没有形参或返回值:
func&printHelloWorld()&{&&&&&println("hello,&world")&}&
这个函数的类型是()-&(),或者"没有形参的函数,并返回void。"没有指明返回值的函数通常会返回void,在swift中相当于一个空元组,显示为()。
使用函数类型
在swift中您可以像任何其他类型一样的使用函数类型。例如,你可以定义一个常量或变量为一个函数类型,并为变量指定一个对应的函数:
var&mathFunction:&(Int,&Int)&-&&Int&=&addTwoInts&
可以解读为:"定义一个名为mathFunction变量,该变量的类型为'一个函数,它接受两个Int值,并返回一个Int值。'设置这个新的变量来引用名为addTwoInts函数。"
该addTwoInts函数具有与mathFunction相同类型的变量,所以这个赋值在能通过swift的类型检查。
现在你可以使用mathFunction来调用指定的函数:
println("Result:&\(mathFunction(2,&3))")&//&prints&"Result:&5"&
具有相同匹配类型的不同函数可以被赋给同一个变量,和非函数类型一样:
mathFunction&=&multiplyTwoInts&println("Result:&\(mathFunction(2,&3))")&//&prints&"Result:&6"&
与其他类型一样,当你给函数赋一个常量或者变量时,你可以让Swift去推断函数的类型。 & &
let&anotherMathFunction&=&addTwoInts&//&anotherMathFunction&is&inferred&to&be&of&type&(Int,&Int)&-&&Int&
作为形参类型的函数类型
您可以使用一个函数类型,如(Int, Int)-&Int作为另一个函数的形参类型。这使你预留了一个函数的某些方面的函数实现,让调用者提供的函数时被调用。
下边的例子打印了上边的数学函数的结果:
func&printMathResult(mathFunction:&(Int,&Int)&-&&Int,&a:&Int,&b:&Int)&{&&&&&println("Result:&\(mathFunction(a,&b))")&}&printMathResult(addTwoInts,&3,&5)&//&prints&"Result:&8"&
这个例子中定义了一个名为printMathResult函数,它有三个形参。第一个形参名为mathFunction,类型为(Int, Int)-&Int。您可以传递任何同类型的函数作为第一个形参的实参。第二和第三个参数a、b都是int类型。被用来作为数学函数的两个输入值。
当printMathResult被调用时,它传递addTwoInt函数,以及整数值3和5。它使用3和5调用了提供的函数,打印的结果是8。
printMathResult的作用是打印调用适当类型的数学函数的结果。该函数真正实现了什么并不重要--它只关心函数的类型是正确的。这使得printMathResult以一种安全类型的方式把自身的功能转换至函数的调用者。
作为返回类型的函数类型
你可以将一个函数类型作为另一个函数的返回类型。你可以在返回函数的返回箭头(-&) 后立即编写一个完整的函数类型来实现。
下面的例子定义了两个简单的函数调用stepForward和stepBackward。stepForward函数返回一个输入值+1的结果,而stepBackward函数返回一个输入值-1的结果。这两个函数都有一个相同的(Int) -& Int类型 :
func&stepForward(input:&Int)&-&&Int&{&&&&&return&input&+&1&}&func&stepBackward(input:&Int)&-&&Int&{&&&&&return&input&-&1&}&
这里有一个chooseStepFunction函数,它的返回类型是"函数类型(Int) -& Int"。chooseStepFunction基于名为backwards的布尔形参返回stepBackward或stepForward函数:
func&chooseStepFunction(backwards:&Bool)&-&&(Int)&-&&Int&{&&&&&return&backwards&?&stepBackward&:&stepForward&}&
你现在可以使用chooseStepFunction获取一个函数,可能是递增函数或递减函数:
var&currentValue&=&3&let&moveNearerToZero&=&chooseStepFunction(currentValue&&&0)&//&moveNearerToZero&now&refers&to&the&stepBackward()&function&
前面的例子可以计算出是否需要通过递增或者递减来让currentValue变量趋于零。currentValue的初始值为3,这意味着currentValue & 0返回为真,并且chooseStepFunction返回stepBackward函数。返回函数的引用存储在一个名为moveNearerToZero的常量里。
如今moveNearerToZero执行了正确的功能,就可以用来计数到零:
println("Counting&to&zero:")&//&Counting&to&zero:&while&currentValue&!=&0&{&&&&&println("\(currentValue)...&")&&&&&currentValue&=&moveNearerToZero(currentValue)&}&println("zero!")&//&3...&//&2...&//&1...&//&zero!&
迄今为止所有你在本章中遇到函数都是全局函数,在全局作用域中定义。其实你还可以在其他函数体中定义函数,被称为嵌套函数。
嵌套函数默认对外界是隐藏的,但仍然可以通过它们包裹的函数调用和使用它。enclosing function也可以返回一个嵌套函数,以便在其他作用域中使用嵌套函数。
你可以重写上面的chooseStepFunction例子使用并返回嵌套函数:
func&chooseStepFunction(backwards:&Bool)&-&&(Int)&-&&Int&{&&&&&func&stepForward(input:&Int)&-&&Int&{&return&input&+&1&}&&&&&func&stepBackward(input:&Int)&-&&Int&{&return&input&-&1&}&&&&&return&backwards&?&stepBackward&:&stepForward&}&var&currentValue&=&-4&let&moveNearerToZero&=&chooseStepFunction(currentValue&&&0)&//&moveNearerToZero&now&refers&to&the&nested&stepForward()&function&while&currentValue&!=&0&{&&&&&println("\(currentValue)...&")&&&&&currentValue&=&moveNearerToZero(currentValue)&}&println("zero!")&//&-4...&//&-3...&//&-2...&//&-1...&//&zero!&
本章由CocoaChina的翻译小组成员&Da杯柠檬水()翻译,转载请注明出处和译者信息,拒绝商业之用。
TA的最新馆藏
喜欢该文的人也喜欢}

我要回帖

更多关于 swift map 函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信