上一篇文章,初步了解了swift与xcode 6的内容。下面继续总结swift语法中的函数与类。
函数与闭包 (Functions and Closures)
swift函数定义规则是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
func 函数名 ( 参数名 : 参数类型 , 参数名 : 参数类型 , . . . ) -> 返回值类型 {
// 函数主体
return ( a , b , c )
}
// 例子
func sumOf ( numbers : Int . . . ) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf () // result : 0
sumOf ( 42 , 597 , 12 ) // result : 651
/*----------- 返回一个函数名,它也是一个内嵌函数 ------------*/
func 函数名 ( 参数名 : 参数类型 , 参数名 : 参数类型 , . . . ) -> ( 参数类型 1 -> 返回类型 1 ) {
func nestedFunc ( 参数名 : 参数类型 1 ) - > 返回类型 1 {
return 返回类型 1
}
return nestedFunc
}
// 例子
func makeIncrementer () -> ( Int -> Int ) {
func addOne ( number : Int ) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer ()
increment ( 7 ) // result : 8
/*----------- 把函数作为函数的一个参数 ------------*/
func 函数名 ( 参数名 : 参数类型 , 函数名 : 参数类型 -> 返回类型 ) -> 返回类型 {
}
// 例子 , 判断是否存在小于 10 的数字
func hasAnyMatches ( list : Int [] , condition : Int -> Bool ) -> Bool {
for item in list {
if condition ( item ) {
return true
}
}
return false
}
func lessThanTen ( number : Int ) -> Bool {
return number < 10
}
var numbers = [ 20 , 19 , 7 , 12 ]
hasAnyMatches ( numbers , lessThanTen )
* 返回类型支持返回多个值。方法是使用括号括住返回值:(rA,rB,rC)
* 参数列表也支持输入一组有效的参数值,将以数组形式传入函数。
* 内嵌函数
函数可以互相嵌套,内部函数可以使用外部函数的值。
* 函数可以作为一个类型被返回。
* 函数可以作为一个参数被传入到另外一个函数。
闭包(Closure)
闭包是一个不显示参数与返回类型的特殊函数,你可以通过闭包来写一个匿名函数,将主体写在{}
中,用in
区分主体
与参数值
、返回类型
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
( 参数名 : 参数类型 ) -> 返回类型 in
// closure body
return 返回类型值
}
// 例子 , 返回一个包含运行闭包后的结果集合。先看看 map 的定义 :
// ————————————— begin —————————————————
// / Return a Array containing the results of calling
// / `transform(x)` on each element `x` of `self`
// / 返回一组 ( 每个子元素都 ) 调用闭包后的结果集合
func map < U > ( transform : ( T ) -> U ) -> U []
// ————————————— end —————————————————
var numbers = [ 20 , 19 , 7 , 12 ]
var result = numbers . map (
{
( number : Int ) -> Int in
let result = 3 * number
return result
})
println ( "\(result)" ) // result : [ 60 , 57 , 21 , 36 ]
var result = sort ( [ 1 , 5 , 3 , 12 , 2 ] ){ $0 > $1 } // 结果执行过程看下图
println ( "\(result)" ); // result : [ 12 , 5 , 3 , 2 , 1 ]
对象和类(Objects and Classes)
类的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class classname : inheritType { // :inheritType 是继承对象。在这里是可选值。
// here is your code
// properties
var aString : String
{
// // 注意不允许在 set 方法中对自身值进行赋值,否则将导致死循环。
// set { // 默认传入值用 newValue 表示,也可以用 set ( newname ) 来设置一个新值的别名
// println ( "set value as \(newValue)" ) // println ( "set value as \(newname)" )
// }
//
// get {
// return self . aString
// }
// // 注意, set 和 get 必须同时存在,否则编译器报错。
// // willSet 和 didSet 必须同时存在。
// // set , get 和 willSet , didSet 不能同时存在
willSet ( anewvalue ){ // 这里使用了新值的别名 anewvalue ,默认为 newValue
println ( "self.aString:\(self.aString) set as newValue:\(anewvalue)" );
}
didSet {
println ( "after set \(self.aString)" );
}
}
// methodes
init (){ // 构造方法,若不添加编译器将会报错。
super . init (); // 调用父类的构造方法。注意:这里必须顺序,先初始化父类构造方法,子类才能调用父类属性与方法。
self . aString = aStr ;
}
deinit { // 析构方法,可选方法:此方法不需要参数
}
/*
override func aFuncInInheritType(){/ / 父类方法重写 . 若需要重写父类方法,可以使用 override 关键字
}
*
}
var aclass : MyClass = MyClass ( aStr : "hello”);//此处willSet和didSet方法不执行。只执行了set和get方法
aclass.aString = " hello , word ” ; // 此处执行 willSet 和 didSet 。说明 willSet 、 didSet 在初始化时不调用, set 、 get 方法每次对其进行赋值,都会被调用。
处理变量的可选值时,你可以在操作(比如方法、属性和子脚本)之前加?。如果?之前的 值是 nil,?后面的东西都会被忽略,并且整个表达式返回 nil。否则,?之后的东西都会被运行。
枚举与结构体(Enumerations and Structures)
枚举用enum来定义:enum 枚举名:枚举类型{枚举体}
,枚举类型可选。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 定义扑克的 A - K ,数值从 1 开始增加,且定义一个 simpleDescription 函数,用于输出切换数值和名称。
enum Rank : Int { // 若去掉 :Int 则不允许赋值 Ace = 1
case Ace = 1
case Two , Three , Four , Five , Six , Seven , Eight , Nine , Ten
case Jack , Queen , King
func simpleDescription () -> String {
switch self {
case Rank . Ace :
return "ace"
case Rank . Jack :
return "jack"
case . Queen : // 可用 `.Queen` 表示 Rank . Queen
return "queen"
case . King :
return "king"
default :
return String ( self . toRaw ())
}
}
}
let queen = Rank . Queen // 枚举一个 ace
let queenRawValue = queen . toRaw () // 切换为数值, result : 12
var des = queen . simpleDescription () // 输出枚举字符描述 , result : ace
if let convertedRank = Rank . fromRaw ( queenRawValue ) { // 将 12 转换为枚举类型,等价于 Rank . Queen
let threeDescription = convertedRank . simpleDescription ()
println ( "\(threeDescription)" )
}
toRaw()转换为数值,fromRaw(avalue)将avalue转换为枚举型。
接口与扩展(Protocols and Extensions)
swift中同样用protocol
来声明接口,类、枚举和结构体都可以实现接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protocol ExampleProtocol {
var simpleDescription : String { get }
mutating func adjust ()
}
class SimpleClass : ExampleProtocol {
var simpleDescription : String = "A very simple class."
var anotherProperty : Int = 69105
func adjust () {
simpleDescription += " Now 100% adjusted."
}
}
struct SimpleStructure : ExampleProtocol {
var simpleDescription : String = "A simple structure"
mutating func adjust () {
simpleDescription += " (adjusted)"
}
}
mutating 用于修饰一个可被修改的函数体。当接口被类继承时,不需要用mutating 来重写方法体,当接口被枚举和结构体的使用,使用mutating关键字来重新修改结构体。
1
2
3
4
5
6
7
8
9
10
11
12
13
extension Int {
func descript () -> String {
return "int value is:\(self)" ;
}
}
extension Int : ExampleProtocol {
var simpleDescription : String {
return "The number \(self)"
}
mutating func adjust () {
self += 42
}
}
使用extension为某个类型扩展变量或者方法。当运行时赋值对象与定义变量类型不符时,只实现变量类型的那部分实现。例如:
1
2
3
4
5
var simpleClassA : SimpleClass = SimpleClass ();
simpleClassA . adjust ();
let protocolValue : ExampleProtocol = simpleClassA ; // 把 simpleClass 类赋值给 protocolValue , protocolValue 为接口类型时,编译器只将 SimpleClass 实现 ExampleProtocol 赋值给 protocolValue ,所以你不能通过 protocolValue 调用 simpleclassA 的属性或方法。
protocolValue . simpleDescription
// protocolValue . anotherProperty // Uncomment to see the error
泛型(Generics)
在尖括号里写一个名字来创建一个泛型函数或者类型。泛型类型可以在函数和方法中使用,也可以在类,枚举和结构体使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 函数定义的乏型
func funcGenerics < T > ( item : T ) -> T [] { // 为方法定义泛型 T , 而 T 的类型是参数的格式(由参数判定) , 返回是参数格式的数组
var a = T [] ();
a += item ;
return a ;
}
let fg = funcGenerics ( ” hello ” ); // 返回一个 String 类型数组
let fg2 = funcGenerics ( 3 . 141592628 ); // 返回一个 Double 型数组。
// 类泛型
class classGenerics < T > {
func method ( a : T ){
println ( a );
}
}
var gClass = classGenerics < String > ();
gClass . method ( "aString" );
// 或者----- Double 类型
var gClass = classGenerics < Double > ();
gClass . method ( 3 . 1415926 );
// 枚举泛型
enum enumGenerics < T > {
case a ;
case b ( T );
mutating func description (){
switch self {
case a : println ( "result is none" );
case b ( var val ) :println ( "result in b(T) is:\(val)”)//定义一个val变狼,类型为T
}
}
}
var eg = enumGenerics<Int>.b(13);
eg.description();
var eg = enumGenerics<String>.b(" a string in enum Generics ");
eg.description();
//结构泛型
struct StructGenerics<T>{
typealias ItemType = T //定义一个T类型别名。
mutating func adjust(a: ItemType) {
println(a);
}
}
var sg = StructGenerics<Int>();
sg.adjust(34);
var sg = StructGenerics<String>();
sg.adjust(" struct result is 34 ");
在类型名后面使用 where 来指定一个需求列表——例如,要限定实现一个协议的类型,需要限定两个类型要相同,或者限定一个类必须有一个特定的父类。
1
2
3
4
5
6
7
8
9
10
11
func anyCommonElements < T , U where T : Sequence , U : Sequence , T . GeneratorType . Element : Equatable , T . GeneratorType . Element == U . GeneratorType . Element > ( lhs : T , rhs : U ) -> Bool {
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
}
}
}
return false
}
anyCommonElements ( [ 1 , 2 , 3 ] , [ 3 ] )