DahuangPhoneiOSSwift → Swift基本语法


  共有10463人关注过本帖树形打印复制链接

主题:Swift基本语法

帅哥哟,离线,有人找我吗?
dahuangphone
  1楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
Swift基本语法  发帖心情 Post By:2014/10/8 11:10:49 [只看该作者]

定义常量:let

定义变量:var

变量定义规范:

常量全部使用大写,多个单词用下划线隔开。

变量使用驼峰写法。

注释:

//   单行,选中多行,使用command+/可以同时注释多行

/*   */   多行,可以嵌套使用


表达式:

1.不指定数据类型:系统自动分配看数据类型

  • var a=2;
  • let b=3;

2.指定数据类型:指定类型,可读性好,推荐

  • var c:Int=4;
  • let d:Int=5;
  • let d:Int=5.5;  //实际值为5
  • let d:Int="5.5";   //报错

布尔型


var b:Bool=true  


注意:

1. 布尔型可以赋值非零值表示true,零表示false。但是必须要先指明Bool类型,否则就是声明了一个整型

2. if语句中的判断条件必须是一个Bool的返回值,即true或者False,不能直接使用整数来作为判断条件



运算符


===:a与b引用一个实例时返回ture,否则false,只用于类

==:比较两个引用的内容是否是同一个实例


%: 余数(取模)


Swift中,整数,负数,浮点都可以求余数,根据以下计算公式:


var array:(CGFloat,CGFloat,CGFloat,CGFloat)=(8.5 % (-2.5), -8.5 % (-2.5), 8.5%2.5, -8.5%2.5)

        

println("\(array)")


结果:(1.0, -1.0, 1.0, -1.0)


因此余数的正负与被除数保持一致,余数大小与被除数和除数的绝对值的余数相同




基本数据类型:

一般使用Int和UInt 。数据会和平台保持一致


var abc=9_600_000


var float1=9_600_000.00   //值为9600000,为了便于查看,数字可以用下划线分开书写


浮点类型的自动推断是Double类型,如果要使用Float,必须指定



各种类型数据进行计算的时候不支持隐形转换,必须强制手动转换。


如果浮点向整形转换,小数点会被忽略。



n进制表达方法:


let decimailInt=28

let binaryInt=0b11100   //0b 开头

let octalInt=0o34       //0o 开头

let hexadecimalInt=0xdd //0x开头

 

元组型:

var tuple1=(1,2,3,4)       //不带键值的定义方法

var tuple2:(Int,Int)=(2,2)       //强制类型定义方法

var tuple3=(id:12,name:333);       //带键值的定义方法

var tuple4:(id: Int, name: Int)=(id:22,name:4444);       //带键值,强制类型定义方法


var t1=tuple4.0       //无键值读取方法(带键值也可以这么读取)

var t2=tuple4.id       //有键值的读取方法




var (ta1,tb1,tc1,td1)=tuple1;       //将元祖分解成多个变量。


println("\(ta1)");


var (t11,_)=tuple2       //如果只需要其中几个,可以讲不用的变量使用下划线代替。


字符串:


var string1=""            //初始化方法一

var string2=String()            //初始化方法二


var string3:String="abc"            //强制类型方法

print(string3)


var count=countElements(string3)            //计算字符串中的字符数量

var string4="\(2)+\(3)=\(5)"            //


let sz1=["abc3.jpg","abc2.jpg","abc1.jpg","abc.bmp","abc.gif","abc.png"]            //

var sameSuffix=0;

var samePrefix=0;


var upperCaseString=""

var lowerCaseString=""


for string in sz1{

    if string.hasSuffix(".jpg"){            //查看字符串是否有指定的后缀

        sameSuffix++;

    }

    if string.hasPrefix("abc."){            //查看字符串是否有指定的前缀

        samePrefix++;

    }

upperCaseString=string.uppercaseString;           //字符串变成大写

    lowerCaseString=string.lowercaseString;           //字符串变成小写

}


 var str="abcdefg"

        

        //获取字符串的每一个字符

        for item:Character in str{

            println(item)

        }

        

        //获取字符串每一个字符的unicode编码

        

        for item in str.unicodeScalars{

            print("\(item.value)")

        }

        


定义别名:


typealias Abc=Int   //typealias和typedef功能相似

var abc:Abc=2


区间值 ...和..<


0...2  包括 0,1,2

0..<2  包括 0,1


使用场景

for i in 0...5{   //注意,这里的 i 不需要var

     print("\(i)")

}

        

for i in 0..<5{

     print("\(i)")

}

        

以及下面的switch中



Swiftswitch用户和其他语言有很大区别:


1. case值不局限于整数,可以是整数、浮点数、字符、字符串、元组等类型。

2.    没有break,当遇到条件匹配的case后,执行完语句就会自动退出switch。(如果加上一个fall through语句,在dang'qian当前case执行完后不跳出,继续执行)

3.    case 支持匹配范围的比较方式


let count1 = 3

let countedThings = "stars in the Milky Way"

var naturalCount: String

switch count1 {

case 0:

    naturalCount = "no"

case 1...3:     //大于等于1,小于等于3, 如果是1..<3, 意思是大于等于1,小于3,不包括3

    naturalCount = "a few"

case 4...9:

    naturalCount = "several"

case 10...99:

    naturalCount = "tens of"

case 100...999:

    naturalCount = "hundreds of"

case 1000...999_999:

    naturalCount = "thousands of"

default:

    naturalCount = "millions and millions of"

}

println("There are \(naturalCount) \(countedThings).")



元组在swift中用于比较:

var stu=(id:"1002",name:"wang",score1:99,score2:70)

var desc:String=""


switch stu{

    case(_,_,90...100,90...100),(_,_,40...70,50...60):

        desc="优秀"

    case(_,_,90..<100,90...100),(_,_,90..<100,60...100):   //这里的都好是“或”的关系

        desc="良好"

    default:

    desc="none"

}


swift中的值绑定和where语句的使用

var stu=(id:"1002",name:"wang",score1:99,score2:90)

var desc:String=""


switch stu{

    case(let id, let name ,90...100,90...100):    // 可以绑定多个值,在case范围里调用。但是这种方式必须只有一个case语句,如果是case(_,_,90..<100,90...100),(_,_,90..<100,60...100)无法绑定

        desc=id + name + "优秀"

case(let id, let name ,90..<100,90...100):

        desc=id + name + "良好"

case(let id,_,90..<100,90...100) where id.toInt()>0:   //可以像sql语句一样查询

        desc="where"

    default:

    desc="none"

}


//元组的判断


var t1=(1,2,3)

        

switch t1{

    case let(_, x,3):   //(_,let x,3) ,两种方式都不能指定类型(x:Int)

         println("\(x)")

    case let(x,y,z) where x==1 && y>1 || z==x+y :  //可以where语句

         println("\(x)")

    default:

         println("none")

}



for in语句,专门用于遍历集合


跳转语句:


var aaa=[1,2,3,4,5,6]


label1:for(var i=0;i<2;i++){

    label2:for(var j=0;j<3;j++){

        if(aaa[3*i+j]>2){

            aaa[3*i+j]=9;

            break label2  //label为跳出label2循环,但是会继续执行label1循环,如果此处为label1,那么就彻底跳出了

        }

    }

}


var aaa3=aaa[2];

aaa3=aaa[3];


continue语句使用方法和break相同




<!--EndFragment-->
[此贴子已经被作者于2014/10/11 17:41:43编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  2楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/8 17:58:28 [只看该作者]

 集合


数组:


var a:Array<String>=["aaa","bbb"];

var b1:[String]=["bbb","bbb"];

var c1:[String]=[String]();  

var c2:[String];

var arrayWith4Elements=Array(count: 4, repeatedValue: 0)  //定义固定长度数组,填充值


c1和c2是有区别的,c1已经初始化,c2只是声明,没有开辟内存空间



a1.append("ccc");  // 追加一个

a1+=["ddd","eee"];   // 追加多个

a1.insert("xxx", atIndex: 0);   // 插入数据

  

a1.removeAtIndex(0);   // 删除数据


a1[0]="fff"



//遍历方式一

for (index,value) in enumerate(a1){ 

    println("item \(index+1):\(value)")

}


//遍历方式二

for item in a1{

    println("\(item)");

}


Swift的数组要求内部数据内类型一致,这个NSArray是不同的,比如下面


var array1=[1,2,3]     //[Int] 类型

var array2=[1,2,"3"]   //NSArray 类型,内部Int会转化为NSNumber,String转化为NSString

        

var arr1: AnyObject!=array2[0]  //此处必须使用AnyObject!,让编译器知道这是对象

        

if var num = arr1 as? NSNumber {

   println("\(num )")

}


结果 1       


字典:


var dict1:Dictionary<Int,String>=[0:"aaa",1:"bbb"];


var dict2:Dictionary<Int,String>=Dictionary<Int,String>();


let dict2:[Int:String]=[Int:String]();


let声明的字典,不但字典自己不能修改,内部元素也不能修改,因为他们是值类型,不是引用类型,数组也一样


字典也要求字典元素与定义类型保持一致,否则会自动转成NSDictionary


dict1[0]="ccc";

dict1[0]=nil;   //删除这个键值对,数组不能这么做

dict1.removeValueForKey(0);

dict1.updateValue("ddd", forKey: 1);//返回值是被替换掉的值,不是替换值


for item in dict1.keys{  //dict1.keys并不是一个数组,需要用 var array=Array(dict1.keys) 才能转成由key组成的数组

    println("\(item)");

}


for item in dict1.values{

    println("\(item)");

}


for (key,value) in dict1{

    println("\(key):\(value)");

}



var  dict1=["k1":"1","k2":2]   //这是一个NSDictionary

        

var str1:String?=dict1["k1"] as? String   //转成String

var str1:String=dict2["k1"]!   //这么写是不可以的,因为dict1["k1"]是一个AnyObject,不能转成String


        

if (str1 != nil) {

   var i1:Int?=str1!.toInt()    //转成Int

   println("\(i1!)")

}

        

var  dict2=["k1":"1","k2":"2"]   //这是一个Dictionary

        

var str2:String=dict2["k1"]!   //提取元素

        

var i2:Int? = str2.toInt()   //转成Int





因为集合在Swift中不算是引用类型,所以当复制或者值传递的时候,总是发生复制行为,但具体元素是否复制要看其类型来决定


[此贴子已经被作者于2014/10/11 17:16:44编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  3楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/8 19:09:27 [只看该作者]

 函数:



var area=0


func rectangleArea(width:Int,height:Int)->Int{

    return width*height;

}

area=rectangleArea(3040);


// -------------------------------------


//默认情况下函数参数都是常量,不可以修改,在前面加上var,既可以变为变量参数,在函数体里可以修改

func rectangleArea( var width:Int,height:Int)->Int{

    return (width++)*height;  

}

area=rectangleArea(3040);


// -------------------------------------


func rectangleArea1(W width:Int,H height:Int)->Int//加上外部参数

    return width*height;

}

area=rectangleArea1(W: 30, H: 40);


// -------------------------------------


func rectangleArea2(#width:Int,#height:Int)->Int{     //将内部参数默认为外部参数

    return width*height;

}

area=rectangleArea2(width: 30, height: 40);


// -------------------------------------


func rectangleArea3(width:Int=60,H height:Int=50)->Int{ //有默认值的参数在调用函数的时候需要加上外部参数或者内部参数来赋值

    return width*height;

}

area=rectangleArea3(width: 40,H: 60);// 2400 有默认值的参数在调用函数的时候需要加上形参:形式来赋值

area=rectangleArea3();           //3000

area=rectangleArea3(width: 40);   //2000

area=rectangleArea3(H: 60);    //3600


// -------------------------------------


func rectangleArea4(width:Int=50,height:Int)->Int{

    return width*height;

}

area=rectangleArea4(60);  //3000, width默认50,高度为60

area=rectangleArea4(width:40,60);  //2400


// -------------------------------------


func rectangleArea5(W width:Int=50,_ height:Int=8)->Int//默认形参前加上下划线,调用时候不用写形参或者外部参数

    return width*height;

}

area=rectangleArea5(W:60,30);  //1800 默认形参前加上下划线,调用时候不用写形参或者外部参数



area=rectangleArea5(W:60);  //480 默认形参前加上下划线,调用时候不用写形参或者外部参数


area=rectangleArea5();   //400


area=rectangleArea5(60);   //3000


// -------------------------------------


可变参数:

func sum(num:Int...)->Int{   num为一个Int数组

    var total=0;

    for item in num{

        total+=item;

    }

    return total;

}


var sum1=sum(1,2,3,4,5,6);  //可以输入任意多个参数


函数参数的传递引用


func increment(inout value:Double,amount:Double=1.0){   //inout 代表传递参数指针(引用)

    value+=amount;

}


var value:Double=10.0;


increment(&value);   //前面要加上&,代表引用

println(value);


increment(&value, amount: 100.0);

println(value);



无返回值函数三种写法:

func  noReturn(){

    

}


func noReturn1()->(){   //返回空的元组


}


func noReturn2()->Void{


}


多返回值函数

一种使用引用参数,另外是返回元组


func position(dt:Double,speed:(x:Int,y:Int))->(x:Int,y:Int){

    var posx:Int=speed.x*Int(dt);

    var posy:Int=speed.y*Int(dt);

    return (posx,posy);

   /*

    var pos:(x:Int,y:Int);

    pos.x=posx;

    pos.y=posy;

    return pos;

*/

}


let move=position(60.0, (10,-5));


函数作为函数返回值或者参数使用


func rectangleArea(width:Double,height:Double)->Double{

    return width*height;

}


func triangleArea(bottom:Double,height:Double)->Double{

    return bottom*height*0.5;

}


func getArea(type:String)->(Double,Double)->Double{   //返回一个函数,这个函数有两个Double参数,返回一个Double

    var returnFunction:(Double,Double)->Double;   //定义一个函数类型,有两个Double参数,返回一个Double

    switch type{

    case "rect":

    returnFunction=rectangleArea;

    case "tria":

    returnFunction=triangleArea;

    default:

        returnFunction=rectangleArea;

    }

    return returnFunction;

}


var area:(Double,Double)->Double=getArea("tria");

println("area:\(area(10,15))");


func getAreaByFunc(funcName:(Double,Double)->Double,a:Double,b:Double)->Double//将函数作为参数

    return funcName(a,b);

}


var result:Double=getAreaByFunc(triangleArea, 10, 15);


//函数重载

Swift函数只要在参数个数、类型,以及返回值的个数,类型有变化的情况下,都可以重载


func receive(i:Int){

    println(i);

}


func receive(i:Double){

    println(i);

}


func receive(i:Int)->Int{

    return i;

}


func receive(i:Int)->Double{

    return Double(i);

}


func receive(i:Int,j:Int){

    println(i);

}


var a:()=receive(1);

var b:Void=receive(2.2);

var c:Int=receive(3);

var d:()=receive(2,3);

var e:Double=receive(4);


//函数嵌套


func calculate(opr:String)->(Int,Int)->Int{

    var c=8;

    //定义嵌套函数,作用域为此函内

    func add(a:Int,b:Int)->Int{

        return a+b+c;

    }

    func sub(a:Int,b:Int)->Int{

        return a-b+c;

    }

    var resultFunc:(Int,Int)->Int;

    

    switch opr{

        case "+":

            resultFunc=add;

        case "-":

            resultFunc=sub;

    default:

        resultFunc=add;

    }

    return resultFunc;  //可以将嵌套函数作为返回值传递出去,这样就可以在此函数体外使用,这个函数体内的值(c)都可以被调用

}


let f1:(Int,Int)->Int=calculate("+");

var f1s=f1(1,2);

println("\(f1(1,2))");


let f2:(Int,Int)->Int=calculate("-");

var f2s=f1(2,1);

println("\(f2(2,1))");


//泛型和泛型函数

func isEquals<T:Comparable>(a:T,b:T)->Bool//T代表泛型,Comparable为遵守的协议

    return (a==b);

}


var isE=isEquals(2, 2);

isE=isEquals(3.5, 4.0);

isE=isEquals("ddd", "ddd");



func add<T,U>(a:T,b:U)->(T,U){  //两个泛型,返回值也为泛型

    return (a,b)

}


var a1:(Int,Double)=add(2, 4.0);

var a2:(String,Int)=add("sdf", 4);


//闭包


//闭包就是一个自包含的匿名函数代码块。格式为{(参数列表)->返回值 in 代码}。它可以引用上下文环境中的代码块。


func calculate(opr:String)->(Int,Int)->Int{

    var c=8;

    //定义嵌套函数,作用域为此函内

    func add(a:Int,b:Int)->Int{

        return a+b+c;

    }

    func sub(a:Int,b:Int)->Int{

        return a-b+c;

    }

    var resultFunc:(Int,Int)->Int;

    

    switch opr{

    case "*":

        resultFunc={$0*$1};

    case "+":

        resultFunc={ a,b in return a+b+c};

    case "-":

        resultFunc={ a,b in a+b};

    default:

        resultFunc={ (a:Int,b:Int)->Int in return a+b+c;}   //闭包写法

    }

    return resultFunc;  //可以将嵌套函数作为返回值传递出去,这样就可以在此函数体外使用

}


let f1:(Int,Int)->Int=calculate("+");

var f1s=f1(1,2);

println("\(f1(1,2))");


//单行闭包简化写法


var closeFunc:(Int,Int)->Int={ (a:Int,b:Int)->Int in return a+b;} //基本写法


//上文形参Swift能够推断出类型,返回值也能推断出来,所以可以简化城下面这种方式


closeFunc={ a,b in return a+b}


//如果闭包只有一条语句,可以把return也省略掉


closeFunc={ a,b in a+b}


//闭包可以用$0$1$2等来代替闭包中的参数。$n表示第n+1个参数。使用这种参数名称缩写,还可以在闭包中声裂参数定义,in也可以省略


closeFunc={$0+$1}


 //多行语句的各种写法,不能省略return


closeFunc={(a:Int,b:Int)->Int in let c=9;return a+b+c;}

closeFunc={a,b in let c=9;return a+b+c;}  //省略参数和返回值定义

closeFunc={let c=9;return $0+$1+c;}   //使用$n代替参数,省略in


//总结,

//1. in何时可以省略:使用$的时候,in可以省略

//2. return何时可以省略:当只有一个语句的时候,return可以省略

//3. 闭包最外面的{}代表闭包范围,然后是匿名函数定义(a:Int,b:Int)->Int,in到}之间部分是函数代码。



var result:Int=closeFunc(1,2);

result={a,b in return a+b}(1,2);  //闭包可以直接带参数。


//尾随闭包


func calculate(opr:String,funN:(Int,Int)->Int){

    switch opr{

        case "+":

            funN(10,5);

    default:

        funN(10,5)

    }

}


calculate("+", {$0+$1});   //正常写法

calculate("+"){$0+$1};  //尾随写法,需要最后函数最后一个参数是闭包或者函数。


//闭包捕获上下文中的变量和常量


func makeArray()->(String)->[String]{

    var ary:[String]=[String]();

    func addElement(element:String)->[String]{

        ary+=element;

        return ary;

    }

    return addElement;

}


let f11=makeArray();

var fResult11=f11("aaa");  //运行完以后,ary这个数组尽管是栈分配,但依然存在,并且最新值被保存, 这一点非常重要

fResult11=f11("bbb");  //fResult11是["aaa","bbb"]

let f111=f11   

fResult11=f111("bbb");   //fResult11是["aaa","bbb","bbb"],说明闭包是引用类型,需要注意。



let f12=makeArray();

var fResult12=f12("aaa");

fResult12=f11("bbb");  //这里面实际上是fResult11 + “bbb” ary始终与makeArray()保持一致


//需要注意,尽管ary是在makeArray函数里面,但是闭包依然可以在外部调用、修改它。


//闭包练习


var array:[Int]=[1,2,4,3];


array.sort({$0<$1});   //


array.sort{$0<$1};   //尾随闭包写法


array.sort({(item1:Int,item2:Int) -> Bool in return item1<item2})  //最普通写法


array.sort({item1,item2 in item1<item2})  //简化参数定义和返回值写法,只有一行代码,省略return


array.sort({(item1,item2) -> Bool in item1<item2})   //简化参数定义写法,只有一行代码,省略return


array.sort({item1,item2 in return item1<item2})   //简化参数定义和返回值写法,


array.sort{item1,item2 in item1<item2}   //闭包尾随写法


println("\(array)");


//变态写法


func add(a:Int,b:Int,c:(Int,Int)->Int)->Int{

            return c(a,b)

}

        

var result=add(1,2,+)  // + 是一个闭包,完整样子是 {(a:Int,b:Int)->Int in return a+b}

        

println("\(result)")


[此贴子已经被作者于2014/10/11 18:53:43编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  4楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/9 15:50:26 [只看该作者]

 //枚举


//定义

enum E1{

    case Monday,Tuesday,Wendnesday,Thursday,Firday   //最后一个没有逗号

}

enum E2{

    case Monday   //没有逗号,这里面的值并不是0

    case Tuesday

    case Wendnesday

    case Thursday

    case Firday

}


enum E3:Int{

    case Monday=0   //没有逗号,下面的值自动加1

    case Tuesday

    case Wendnesday

    case Thursday=5

    case Firday

}


//赋值:


var ae1:E1=E1.Monday

var ae2=E2.Monday

var ae3=E3.Monday   //虽然E3Monday的值是0,但是不代表ae3的值是0


var ae3Value=ae3.toRaw();  //这个值才是0 ae3没有toRaw这个方法。


var ae31=E3.fromRaw(ae3Value//ae3=ae31


//枚举和switch的使用


//枚举中的每一个值都必须在switchcase体现,如果在case中体现了,可以省略default


switch ae1{

    case .Monday:

        println("mon")

    case .Tuesday:

        println("2,3")

    case .Wendnesday:

        println("2,3")

    case .Thursday,.Firday:

        println("4,5")

    default:

    println("4,5")


}


//枚举中为元组


enum E4{

    case C1(Int,Int)

    case C2(Int)

}


func printE4(e4:E4){

    switch e4{

    case .C1(let x, let y):  //注意取值的写法

        println("\(x+y)")

    case let .C2(x):    //如果所有制都要取出来,也可以这么写

        println("\(x)")  

    }

}


printE4(E4.C1(2, 3));

[此贴子已经被作者于2014/10/9 15:53:15编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  5楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/9 16:45:53 [只看该作者]

 //Swift中结构体和类的对比

//两者都可以定义成员变量,成员方法,都有下标和构造器

//结构体没有继承性,不具备运行时轻质类型转换、使用析构器和使用引用计能力


//定义


class Aclass{

    

}


struct Astruct{

    

}


class Emplyee{

    var no:Int=0

    var name:String=""

    var job:String?

    var salary:Double=0.0

    

    var dept:Department?

}


struct Department{

    var no:Int=0

    var name:String=""

}



var dept=Department()


dept.no=10

dept.name="Sales"



var emp=Emplyee()

emp.no=1000

emp.name="Martin"

emp.job="Salesman"

emp.salary=12200

emp.dept=dept


func updateDept(inout dept:Department){  //此处必须使用inout代表引用,因为结构体是值类型

    dept.no=3333

}


func updateEmp(emp:Emplyee){  // 这里不需要inout,因为类是引用类型

    emp.no=4444

}


updateDept(&dept);

updateEmp(emp);


var emp1=emp


var isE=emp===emp1  //就是确定是否指向同一个地址


var dept1=dept


isE=dept==dept1  //这么写必须要在结构体内重写==运算符,定义相等规则


//类型嵌套

//优点,便于访问类型外部类成员

//缺点,可读性差


class Emplyee{

    var no:Int=0

    var name:String=""

    var job:String?

    var salary:Double=0.0

    

    var dept:Department=Department()

    

    var day:Weekday=Weekday.Wendnesday

    

    struct Department{

        var no:Int=0

        var name:String=""

    }

    

    enum Weekday{

        case Monday,Tuesday,Wendnesday,Thursday,Firday   //最后一个没有逗号

        

        struct Day{

            static var message:String="Today is..."

        }

    }

}


var emp=Emplyee()


let wendesday=Emplyee.Weekday.Wendnesday

if(wendesday==emp.day){

    println("==")

}


var message=Emplyee.Weekday.Day.message



[此贴子已经被作者于2014/10/9 17:47:09编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  6楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/9 17:47:20 [只看该作者]

 


// 可选类型与可选链 ! 的作用


// 类型后面加上?(不能有空格)代表可能是这个类型,可能什么都不是,但绝对不会是别的类型

var x:Int//代表x可能是一个int类型,也可能什么都不是,但是绝对不会是其他类型


//在一个可选类型变量后面加上!(不能有空格),代表确定这个变量有值,可以直接读取,但是如果这个变量没有值,就会crash


//因此对于可选值,一定要先用if判断是有值,再用!读取


func divide(a:Int,b:Int)->Double?{  //这个函数可能返回一个double,也可能是nil,所以返回值要加上一个?

    if b==0 {

        return nil

    }

    return Double(a)/Double(b)

}


let result:Double?=divide(0, 1//读取函数的返回值也要用可选类型


var res:Bool=true

var re:Double=0


if result{

    re=result//此处必须用!读取

}else{

    println("error")

}


//普遍使用判断方法如下


if let result=divide(3, 0){   //这里的let result可能是一个nil也可能是一个double,但都会确定数据类型

    re=result  //这行就不用!来读取数据

}else{

    println("error")

    re=0

}


// 对于带有?的数据类型,什么时候加!什么时候不加,当单独使用的时候可以不加!,但是如果要与其他数据进行运算操作,一定要加!,否则编译器无法知道这个数据会返回什么类型,不能计算



//可选链


class Emplyee{

    var no:Int=0

    var name:String=""

    var job:String?

    var salary:Double=0.0

    

    var dept:Department?

}


struct Department{

    var no:Int=0

    var name:String=""

}


var emp=Emplyee()

var deptName=emp.dept?.name //此处的问号为可选链,一旦emp.deptnil,可以返回nil,如果使用!而又为nilcrash

[此贴子已经被作者于2014/10/11 15:40:21编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  7楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/10 9:42:24 [只看该作者]

 //延时加载


class Emplyee{

    var no:Int=0

    var name:String=""

    lazy var dept:Department=Department()  //lazy,延时加载,只能用于var,不能用于let,用的时候才会初始化,否则不会不初始化,可以减少占用内存

}


struct Department{

    var no:Int=0

    var name:String=""

}



var emp=Emplyee();   //{no 0 name "" nil},dept并没有加载

emp.dept.no=2   //dept加载


//计算属性: 类,结构体,枚举,都可以具有计算属性,设置方法一样

//属性观察者,可以监听属性的变化,即使前后变化相同也可以,不能用于延时储存属性和常量属性的变化,应用范围类和结构体

//静态属性:属性和个体无关,整个类,结构体、枚举共享一个值得属性,称为静态属性或者类属性

//方法是在面向对象(类,结构体,枚举)内的函数,分为实例方法和静态(类型)方法

//静态方法和静态属性都不能方式实例属性和方法的内容


//willSet,didSet不能和get,set同时使用  ,但这几个在全局变量上也可以使用


class Emplyee{

    //储存属性

    var no:Int=0

    

    var willSetFirstName:Bool=false

    

    //属性观察者

    var firstName:String=""{

    willSet(newNameValue){   //将要赋予新值的时候调用,如果删除(newNameValue),默认参数是newValue

        self.willSetFirstName=true

        println("new name :\(newNameValue)")

    }

    didSet(oldNameValue){   //设置完新值后调用,如果删除(oldNameValue),默认值是oldValue

        println("old name : \(oldNameValue)")

    }

    }

    //属性观察者

    

    

    class var printEmpCount:String{ //静态计算属性,用class而不是static

        get{

            return "count:"

    }

    }


    


    var lastName:String=""

    lazy var dept:Department=Department()  //lazy,延时加载,用的时候才会初始化,否则不会不初始化,可以减少占用内存

    

    //计算属性

    var fullName:String{   //必须采用var声明

    get{      //getter访问器

        return firstName+"."+lastName

    }

    //setter访问器,

    //newFullName可以使用默认形参值newValue而省略

    set(newFullName){

        var name=newFullName.componentsSeparatedByString(".")

        firstName=name[0]

        lastName=name[1]

    }

    }

    

    var printName:String{   //只读计算属性,没有setter,下面内容是getter方法。只读属性不能只删除set保留get那么写,那样set依然存在

    return "This is "+lastName+"."+firstName

    }

    

    //实例方法 可以自动将形参变为外部参数,而函数必须在形参前面加#

    func sayName(){

        println(self.fullName)

    }

    

    func sayFullName(fristName:String, lastName:String)->String{

        Emplyee.staticFunc()   // 内部调用静态方法

        return (fristName+"."+lastName)

    }

    

    class func staticFunc(){   //静态方法,class标示,而不是static

        println("this is a staticFunc");

    }

    

}


struct Department{

    var no:Int=0

    var name:String=""

    

    //枚举和结构体方法不能都修改内部属性,必须在方法前面加上 mutating 标示

    //实例方法

    mutating func changeName(newName:String){

        self.name=newName

    }

    

    //静态方法

    static func staticFunc(){

        println("this is staticFunc")

    }

}



var emp=Emplyee();

emp.willSetFirstName

emp.firstName="alex"

emp.willSetFirstName

emp.lastName="wang"

emp.fullName

emp.printName


//调用实例方法

emp.sayFullName("alex", lastName: "wang");

//调用静态方法

Emplyee.staticFunc();



//调用实例方法

emp.dept.changeName("maketing")

//调用静态方法

Department.staticFunc();


//枚举计算属性


enum E:String{

    case a="a"

    case b="b"

    

    static var enumCount:Int=0  //静态储存属性

    

    

    var abc:String{

    return "abc"+self.toRaw()

    }

}


<!--StartFragment--> <!--EndFragment-->
面向对象类型属性
面向对象类型 实例存储属性 静态存储属性 实例计算属性 静态计算属性
支持 不支持 支持 支持
结构体 支持 支持 支持 支持
枚举 不支持 支持 支持 支持
[此贴子已经被作者于2014/10/11 19:27:26编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  8楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/10 14:08:34 [只看该作者]

//构造器,尽在类和结构体存在

//析构函数尽在类中有


class Emplyee{

    var no:Int=0

    var age:Int

    var name:Int?

    

    init(age:Int,no:Int){

        self.age=age

        self.no=no

    }

    

     convenience init(){  //便利构造器,又叫横向构造器,用于同类中的构造器代理

        self.init(age:0,no:0)

    }

    

    deinit//注意写法,没有()

        println("调用析构函数中")

        self.age=0

    }

    

}


class coder:Emplyee{

    var skill:String=""

    //指定构造器必须先初始化自己成员属性,然后再必须调用父类指定构造器

    init(age: Int, no: Int,skill:String) {

        self.skill=skill   //必须在前面

        super.init(age: age, no: no) //这个运行完以后才可以读取实例属性和方法

    }

    //便利构造器必须先调用同类其他构造器,一直到调用指定构造器位置,调用后才可以修改属性

    convenience init(skill:String){

        self.init(age:0,no:0,skill:"");

        self.skill=skill    //必须在后面

    }

}



struct Department{

    var no:Int=0

    var name:String?

    static var countNum:Int?

    var width:Int=0

    var height:Int=0

    

    init(){

        if Department.countNum{

            Department.countNum=Department.countNum!+1

        }else{

            Department.countNum=1

        }

        

        self.init(W:0,H:0) //值类型构造器代理

    }

    

    init(width:Int,height:Int){

        self.width=width

        self.height=height

    }

    

    init(W width:Int,H height:Int){

        self.width=width

        self.height=height

    }

    

    init(length:Int){

        self.init(width:length,height:length)  //值类型构造器代理

    }

    

}


//构造器调用规则


1. 子类指定构造器必须调用其父类的指定构造器

2. 便利构造器必须调用同类中其他构造器

3. 便利构造器必须最终以调用一个指定构造器结束



4. 子类构造器必须保证在所有子类存储属性都初始化完以后才能向上调用父类构造器

5. 子类必须先向上调用父类构造器,然后再为继承的属性设置新值,否则新值会被父类构造器覆盖。

6. 便利构造器必须先调用同类中其他构造器,再为任意属性赋值,否则会被其他构造器覆盖。

7. 构造器在完成第一阶段(走完super.init)之前, 不能调用实例方法,也不能读取实例属性


8. 如果子类没有定义任何指定构造器,那么将继承所有父类的指定构造器

9. 如果子类提供了所有父类指定构造器的实现,那么将自动继承父类的便利构造器


[此贴子已经被作者于2014/10/10 14:58:06编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  9楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/10 15:44:19 [只看该作者]

//重写


class Person{

    var name:String=""

    var age:UInt=0

    

    var printPerson:String{

        return name

    }

    

    init(name:String,age:UInt){


        self.name=name

        self.age=age

    }

    

    func aFunc(){

    

    }

    

    class func aStaticFunc(){

    

    }


    

    

}


class Child:Person{

    var height:UInt=0

    

    override var name:String{

    willSet{

        println("will set")

    }

    didSet{

        println("did set")

    }

    


    }

    

    override var age:UInt{

    get{

        return super.age

    }

    set{

        super.age=newValue>0 ? newValue:0

    }

    }

    

    override var printPerson:String{

        if super.age>20{

            return super.name

        }else{

            return "override var printPerson"

        }

    }

    

    init(name:String,age:UInt){

        self.height=0

        super.init(name:name,age:age)

        super.age=4  // 等价于 self.age=4


    }

    

    convenience init(height:UInt){

        self.init(name: "",age: 0)

        

    }

    

    override func aFunc(){   //重写方法

        

    }

    

    override class func aStaticFunc(){    //重写静态方法

        

    }

    

}


//属性重写可以为父类储存属性重写观察者属性,也可以将父类的存储属性在子类中以计算属性体现


//对于继承过来储存属性,子类只能进行计算,存储在父类那里


//在类以及类的属性、方法前面标注 final,时,表示这个类或者类的属性、方法,不能被重写

[此贴子已经被作者于2014/10/10 15:51:36编辑过]

 回到顶部
帅哥哟,离线,有人找我吗?
dahuangphone
  10楼 | 信息 | 搜索 | 邮箱 | 主页 | UC


加好友 发短信
等级:管理员 帖子:407 积分:4533 威望:0 精华:0 注册:2012/9/29 7:54:10
  发帖心情 Post By:2014/10/10 16:10:42 [只看该作者]

 // is   as   Any  AnyObject

class Person{

}


class Student:Person{

    

}


class Worker:Person{

    

}


var s1=Student()

var s2=Student()

var s3=Student()

var s4=Student()


var w1=Worker()

var w2=Worker()

var w3=Worker()


var stuCount=0

var workerCount=0


let person:[Person]=[s1,s2,s3,s4,w1,w2,w3]


for item in person{

    if item is Student//is用来判断一个对象是否是一个类的实例

        stuCount++

    }else if item is Worker{

        workerCount++

    }

}


stuCount

workerCount


var p1:Person=Person()

var p2:Person=Student()

var p3:Person=Worker()


if let s1=p2 as? Student//as用来把一个对象从一个类型转换成另一个类型,如果不能确定是否可以转换成功,可以使用as?,成功返回转换后对象,不成功返回nil

    println("student")

}



//Any 可以代表任何类型数据,包括类和其他类型数据

//AnyObject 可以代表任何类的实例


var anything:Any=Person()

anything=1

anything="Person()"


var anyObj:AnyObject=Person()

anyObj=Student()


 回到顶部
总数 11 1 2 下一页