Swift入门[基于Java基础]

Swift入门

学习目标

由于已经有了Java编程思想,所以着重了解Swift语言特有的特性,与Java不一样的地方。最终目的是可以使用Swift语言开发iOS应用。

学习过程

学习内容

The Basics [Swift概览]
  • Swfit是类型安全的语言。变量的类型是确定的。不同于PHP,PHP类型是不确定的。

  • Swift结束不用添加分号;,这点与Java不同。

  • 数据类型。Swift的基础数据类型有表示整型的Int,表示浮点型的Double和Float,表示布尔值的Bool,表示字符串的String。集合类型有标识数组的Array,表示无序集合的Set,表示映射关系的Dictionary。Swfit还提供自己特有的类型:元组.元组没有具体的关键字,表达形式是(value1,valule2...);

  • 声明方式。Swift的声明方式只有两种,通过关键字 let和var。这点区别与Java的变量声明。let声明的变量类似于Java通过final声明的变量,不可修改。var声明的变量可以被修改。声明的变量,使用前必须初始化(可选类型除外)。下面是变量max的几种声明方式:

    let max = 10; //明确了 max的类型是Int.
    let max :Int ://同样明确了max的类型是Int.因为这里没有确定初始值,所以使用前必须赋值,否则会报错。
    var max = 10//max可以改变成其他值,而let声明的就不可以。
    
  • 在字符串中连接变量值可以通过 (变量名称)方式。例如

    let name = "Zhouztashin";
    NSLog("my name is \(name)");
    
  • Int类型区分。Swift语言,Int类型同样有有符号和无符号的区分和位数的区分。一般,我们使用Int就可以了,当前平台是32位,它就是32(Int32)的。无符号的Int类型U开头,例如UInt32。

  • Double表示64位的浮点数,Float表示32位的浮点数。

  • 类型别名。Swift提供类型别名的机制,提高代码可阅读性。使用关键字 typealias可以为类型指定别名:

    typealias AudioSample= UInt16;//为UInt16指定别名。
    
  • 可选概念。Swfit里面有一个"Optionals"概念。例如某个变量可以有值,也可以没有值。这就是可选的概念。没有值使用nil表示。使用?符号声明的变量就是可选变量,可选变量可以被赋值为nil。非可选变量不能为nil。

  • 可选概念使用方式。Swfit提供了一种可选概念的使用方式:

    //语法
     if let 变量名  = 可选语句{
    //如果赋值最终不等于nil 则执行这里的语句
    }else{
    //赋值等于nil ,则执行这里。
    }
    
    //例子
    //强制转换 字符串 "not Number"为Int,结果是失败,所以number =nil;
    if let number = Int("not Number"){
    //由于number=nil,所以这里不会被执行
    }
    
  • Swfit也提供了异常处理机制,类似于Java的异常处理机制。

Basic Operators [Swfit 操作符]
  • 各类操作符与Java是一致的。
  • 操作符号的左右两边要留出空格,不然会报错。
  • nil值操作符。Swfit提供了??操作符。
    let valueA = "A";
    var valueB: String?
    var result = valueB ?? valueA; //如果valueB 为nil,那么就将valueA的值给result.
    
  • 范围操作符。Swfit提供范围操作符号"a...b".指定了 从a到b。
    for index in 1...5{
    //这里循环5次,从1到5。
    }
    
  • 半开范围操作符。Swift提供了半开操作符 "a..<b",类似于范围操作符。
    for index in 0..<10{
    //循环10次,从0到9.
    }
    
Strings and Characters [字符和字符串]
  • 字符串声明方式。
    var emptySting = "";
    var anotherEmptyString = String();
    
  • 字符声明方式。
    let singleChar : Character;
    
  • 字符串是值类型。不是引用类型。这一点需要与Java区分。
  • 字符串拼接。字符串拼接可以通过"+";
  • 可以通过 (变量)方法在字符串里面嵌入变量值。例如
    let name = "Zhouztashin";
    print("My name is \(name)");//会打印出 My name is Zhouztashin。
    
  • Swift提供了判断是否有相同前后缀的功能。例如。
    let str1 = "LiXX";
    let str2 = "ssLi";
    
  • Swfit提供了Unicode的访问形式。"\u{代号}"
  • 常用方法。
    var name = "Zhouztashin";
    1、name.isEmpty  //空判断
    2、for character in name.characters{//遍历打印字符
          print(character);//打印单个字符
    }
    3、name.count;//获取字符串数量
    4、name[index];//获取某个下标位置的字符
    5、name.insert("My name is",at :0);//在下标0的位置插入字符串。
    6、name.remove(at :0);//移除下标为0的字符。
    7、name.hasPrefix("Zhou") // 前缀判断,因为有前缀Zhou,所以结果为true;
    8、name.hasSuffic("shin")//因为有后缀shin,所以结果为true;
    
Collection Types [集合]
  • 集合数据类型。Swift提供了三种集合的数据类型。Array,Set,Dictionary。其中Array类比于Java的列表和数组,Set类比Java的Set,Dictionary类比Java的Map。
  • 集合可变与不可变。不同于Java语言,因为Swift集合类型是值类型,所以,Swfif的集合类型如果被声明为let的话,该集合本身和其包括的数据均不能变动。
  • 集合元素访问&赋值方式。Array可以通过数字下标方式访问和赋值,Set则需要通过特定的SetIndex<>下标访问。Dictionary可以通过Key以下标的方式访问相应值。
  • 集合通用方法。空判断(isEmpty)和获取数量(count)的方法是通用的。
  • Array声明方式:
    var someInts :Array<Int>;//声明一个未初始化的Int 列表类型。
    var someInts :[Int];//简约声明方式。
    var someInts = [Int]();//简约初始化空方式。
    var someInts = [];//当someInts已声明了具体类型,那么可以通过[]将该列表置为空
    var someInts  = [12,23];//简约初始化赋值方式。
    var threeDoubles = Array(repeating :0,0,count:3);//特定声明方式,结果会生成 [0,0,0,0,0,0];
    
  • Array常用方法。与第2节字符串操作所用的方法是一样的。
  • Array遍历方式:
    var someInts = [1,2,3];
    1)、遍历元素
    for item in someInts{
    print(item);//打印1,2,3
    }
    2)、遍历下标和元素
    for (index, value) in someInts.enumerated(){
    print("\(index) AND \(value)");
    }
    
  • Set声明方式:
    var someInts :Set<Int>;//声明一个未初始化的Int 列表类型。
    var someInts :Set = [Int]();//简约初始化空方式。
    var someInts = [];//当someInts已声明了具体类型,那么可以通过[]将该列表置为空
    var someInts :Set = [12,23];//简约初始化赋值方式。
    
  • Set常用方法。与第2节字符串操作所用的方法是一样的。
  • Set遍历方式。与Array类似。
  • Dictionary声明方式:
    var someDictionary = String : String;//声明一个字符串与字符串的映射字典。
    var someDictionary :[String : String];
    var someDictionary = ["Zhou":"ZeXuan","Zhong":"Hong"];//以:符号分割键值对。
    var simeDictionary = [:];//将该字典变量置为空。
  • Dictionary常用方法:
    var someDictionary = ["Zhou":"ZeXuan","Zhong":"Hong"];
    1)、更新键值对。[也可以通过下标方式]
    someDictionary.updateValue("Yong",forKey:"Zhong");//更新键为Zhong的值为 "Yong";
    2)、移除键值对。
    someDictionary.removeValue(forKey:"Zhong");//移除键为Zhong的键值对。
    
  • Dictionary 遍历方式:
    var someDictionary = ["Zhou":"ZeXuan","Zhong":"Hong"];
    //遍历获取键值对
    for (key,value) in someDictionary{
    print("\(key),\(value)");//打印出 Zhou,ZeXuan。Zhong,Hong。
    }
    //遍历键。
    for key in somDictionary.keys{
    print(key);//打印键。
    }
    //遍历值
    for value in someDictionary.values{
    print(value);//打印值
    }
    
  • 获取键值对列表。通过 let keys = [String] ta(someDictionary.keys) 获取键列表。值也一样,不过把调用的方法从keys改为values。
Control Flow [控制流程]
  • Swift提供了的判断流程、循环流程,选择流程。这里仅列出常用的使用方式。

  • Swift提供了continue,return,break跳出当前控制流程。与Java一致。

  • 判断流程。与Java类似,采用if else关键字。不同的是不需要使用()将条件包括起来。

    //语法格式
    if  条件 {
    }else{
    }
    //例子
    var year = 1;
    if year == 1 {
    print("我一岁");//打印此语句.
    } else{
    }
    
  • 选择流程。选择流程也与Java类似,采用switch cas关键字。不同的是Swift的switch不需要break;语句跳出当前匹配代码段。如果需要延续下面匹配值的代码段,则需要使用fallthrough语句,只会延续一个匹配值。

    //语法格式。
    switch 值 {
    case 值1:
    执行代码段;
    case 值..:
    执行代码段;
    default:
    未匹配到则执行这里。
    }
    //例子:
    var year  =1;
    switch year{
    case 1:
     	print("我1岁");
    case 2:
    print("我两岁");
    }
    //结果是打印 我1岁;
    
  • 循环流程。Swift同样提供了for 跟while 循环语句。while语句与Java一致。这里只说for语句

    //语法格式
    for 变量  in 范围{
    }
    //其中范围采用了Swfit特有的范围操作符。
    //例子
    for index in 1...10{
    print(index);//打印1到10.如果需要只打印1到9,那么应该使用  1...<10。
    }
    
  • Swfit提供了简约的变量赋值语句。使用了关键字guard。

    //例子
    guard let name = Int("Zhou") else{
    //赋值不成功则执行这里。
    }
    
Functions [方法]
  • Swift方法声明与调用方式。Swift的调用方式与Java有一些区别,Swfit调用方法需要指定相应的参数名称。
    //声明格式。
    func 方法名 (参数名:参数类型,...) ->返回值类型{
    return;
    }
    //例子。
    func isNumber2(number : Int) ->Bool{
    if number ==2 {
    return true;
    }else{
    return false;
    }
    }
    //调用
    let is2 = isNumber2(number: 2);//调用的时候需要指定参数名称。
    print(is2);//输出true;
    
  • 调用方法不需要输入参数名称的方式。通过在参数名称前面添加 "_"符号就可以在调用的时候不指定参数名称。例如
    //调用时:isNumber2(2);//由于声明的时候参数添加了 "_",所以不需要参数名称。
     func isNumber2(_ number :Int) ->Bool{ ...}
    
  • 默认参数值。可以为参数指定默认值。通过在声明的时候赋值,就可以为参数添加默认值。
    //为参数number添加了默认值 3,调用的时候可以不用传入该参数值。
    func isNumber2 (number :Int = 3) ->Bool{...}
    
  • 可变的参数值。可以为不指定参数的数量。声明的时候添加"...".例如:
    //可变的参数声明。调用的时候可以传入不等长度的参数。例如 isNumber2(12.3,34.4); isNumber2(12.4);
    func isNumber2(number : Double ...)->Bool{};
    
  • in-out 参数方式。类似于C语言中的引用传递。由于Swift Int等基本类型是值类型,所以在方法中改变该值只在该方法范围内有效。而通过指定参数为inout类型,那么就会影响到方法外该变量的值。
  • 方法也可以是一个变量参数。Swift提供了一个特性,方法也可以是一个变量或者参数。
Closures [闭包]
  • 闭包的应用之一,参数为方法的时候的简约调用方式。
    //语法
    {
    (参数) -> 返回值  in
    代码段
    }
    //例子
    let array  = ["Str1","Str2"];
    array.sorted(by: {(s1:String,s2:String)->Bool in return s1>s2});
    //更简约的方式
    array.sorted(by :{ s1,s2 in return s1 >s2});//因为参数和返回值是确定的所以不用再描述。
    
Enumerations [枚举]
  • Swift提供的枚举类型跟Java类似。但是比Java要更加好用些,例如Swfit可以给枚举项直接添加对应值。
    //语法。
    enum 枚举名称{
    case 枚举项
    case 枚举项2
    }
    或者
    enum 枚举名称{
    case 枚举项1,枚举项2,枚举项3..
    }
    //例子
    enum CompassPoint{
    case north
    case south
    case east
    case west
    }
    //引用方式
    var directionTohead = CompassPoint.north;
    directionTohead = .east;//因为变量指定了CompassPoint类型,所以可以用这种简约的赋值方式。
    
  • Swfit提供给枚举类型添加相应的值。
    //语法
    enum 枚举名称 : 值类型{
    case 枚举项 = 值;
    case ..
    }
    //例子
    enum Planet : Int{
    case mercury  = 1, venus;//mercury 对应的值为 1;
    }
    //引用方式
    let mercuryValue = Planet.mercury.rawValue;//通过关键字rawValue获取值。
    
  • 可以通过枚举类的值获取对应的枚举项。
    let somePlanet = Planet (rawValue : 1);//这里查找值为1的枚举项,结果为mercury。
    
Classes and Structures [类和结构体]
  • Swift提供了两种块结构。类和结构体。类与结构体的结构和作用是类似的,只不过在不同的应用场景下需要选择相应的结构。这两者跟Java的类是类似的,都由成员变量,成员方法构成。但是区别于Java的是类的文件名称跟里面实际声明的类的名称并不需要一致。
  • 声明方式和实例化方式
    //声明方式
    1) struct 结构体名称{ //结构体声明方式
    //变量
    //方法
    }
    2) class 类名称{ //类声明方式
    //变量
    //方法
    }
    //实例化 
    struct Circle {
    var width :Int;
    var height :Int;
    }
    let circle = Circle();//实例化类或者结构体
    
  • 类和结构体的区别。
    1)、类是引用类型。而结构体和枚举类是值类型。
    2)、结构体倾向用于封装一些简单的数据。
    3)、类可以继承,而结构体无法被继承。
    4)、类和结构体的存储成员变量(区别与计算变量)需要在声明或者在构造函数中被初始化,否则会报错。如果有一个存储成员变量没有初始,那么在实例化的时候需要通过这个全量结构函数传入所有值,否则会报错。类和结构体默认添加了一个全量的初始化方法。
  • 判断类指向同一个实例。通过“=”和“!”判断两个变量是否引向同一个实例。
  • Swift的String、Array、Dictionary、Set都是结构体,所以他们都是值类型。
Properties [属性/成员变量]
  • Swfit将属性按照作用分为两类,一类是存储变量,一类是计算变量,这与Java的成员变量区别很大的一点。另外跟Java一样,Swift也有成员变量和类变量的区分,一样使用static 修饰词。
  • 存储变量与Java的成员变量是一致的。计算变量的声明方式
    struct Point{
    var x = 0,0,y = 0.0;
    }
    struct Rect{
    var origin = Point();
    var center :Point{ //center则是Swift语法中的计算变量。重新定义了获取和赋值的操作。
    get{
    return Point(x :2.2,y:23.3);
    }
    //如果没有写newCenter,那么默认设置的变量名是newValue,如果没有写set方法,就说明该计算变量只可读。
    set(newCenter){ 
    origin.x = 2;
    origin.y = 3;
    }
    }
    }
    
  • Swift成员变量调用方式。
    struct Point{
    var x = 0.0,y = 0.0;
    }
    var point = Point();
    let x = point.x;//获取成员变量x的值。
    point.x = 1.3;//更改成员变量x的值。
    
  • 成员变量观察者。成员变量支持赋值改变前后的观察通知。通过willSet 和 didSet方法可以得知成员变量被改变的前后。
    //语法
    class 名称{
    var 变量 :类型{
        willSet(新的变量值名称){ //改变值前的回调
          //
          }
        didSet{//改变值后的回调
         }
      }
    }
    
Methods [方法]
  • 方法类型。Swift中的方法跟Java一样也分为实例方法和类方法。跟Java一样,类方法也是通过添加static修饰词。
  • 关键字 self.self代表结构体、类本身。与Java的this关键字相似。
  • 方法内改变成员变量值。在结构体或者枚举类里面不可以直接改变成员变量值,需要使用关键字 mutating修饰方法才可以修改成员变量。
Inheritance [继承]
  • Swift中的类可以被继承。跟Java一样,也支持多态。
    //语法
     class 名称 : 父类名称{
    // 
    }
    //例子
     class Father {
     }
    class Son : Father{
    }
    
  • 重写方法。Swift一样可以重写父类的方法。通过关键字override。
  • 调用父类的方法和成员变量。通过关键字super可以调用父类的方法和成员变量。
  • 重写成员变量。不但可以重写方法,Swift也可以重写成员变量的方法和观察者。
    //例子
    class 类名称{
          override var current :Double{ //重写的时候需要重新声明变量。
              didSet{
              //
              }
          }
    }
    
  • 同样,通过final 声明可以防止重写。
Initalizers [初始化]
  • 初始化类似于Java的构造函数。与Java用类名表示构造函数不同的是,Swift通过 init表示构造函数。
  • Swift将构造函数分为了两类,一类是Designated 初始化方法 和Convenience初始化方法。其中Designated就是Java中的构造函数,Convenience就是Swift对外调用提供的简约式声明方式,convenidence修饰的构造方法必须调用Designated 方法。这样重载简约的构造方法的逻辑会清晰很多,因为一定会调用普通的构造方法。
  • Swift还提供可选式样的构造函数,类似于Option值。
Deinitialization [析构函数]
  • 类似与Java类中的finalize函数。当该类实例被回收的时候就会调用该方法。方法的声明方式:
    deinit{
    //处理代码
    }
    
Automatic Reference Counting [自动引用计数器]
  • Swift也跟Java一样也有对引用的自动回收机制。
  • Swift引用计数原理。Swift的引用计数系统会跟踪属性、常量、变量对类实例的引用,如果有存在一个引用以上,则不销毁该实例。
  • 强引用循环问题。Swfit会出现强引用循环的问题,就是类实例A引用了类实例B,两者相互引用。Swift提供的解决方案是使用weak修饰符让变量成为弱引用。与Java的弱引用同出一辙。
Error Handing [异常处理]
  • Swift同样提供了异常处理的机制。跟Java的异常机制类似。
    1)、抛出异常.
    func throwsException () throws {
    throw 异常信息
    }
    2)、不处理异常,继续抛出异常
    func throwsExceptionGoOn ()throws{
    try throwsException();
    }
    3)、处理异常。
    func handleException(){
          do
          {
          try throwsException();//这里可能抛出异常 
          }catch(){//匹配异常
          //处理异常。
          }catch(){
          //处理异常2
        }
    }
    
  • Java有finally{}模块可以确保一些结束操作可以被执行,而Swift也提供了类似的机制,通过defer关键字可以确保里面的代码段在最后被执行。需要注意的是defer句子应该在异常代码之前被声明。并且会先于catch模块前执行。
    func processFile(filename : String) trhows{
    let file open(filename);
    defer{ //这里的代码段会在该范围内所有代码都执行完毕才执行。
      close(filename);//执行关闭操作。
      }
    }
    
Type Casting [类型转换]
  • Swift提供了两种类型转换相关的语法。一种是判断,一种是转换。通过 is 关键字可以判断某个变量是否是某种类型,通过 as? 和 as!转换类型。is类似与Java InstanceOf的关键字,as类似与Java中的强制转换()。

    1) 、is。判断某个变量是否是某种类型或者某种类型的子类。
    class Animal{
    }
    let animal = Animal():
    if(animal is Animal){
    //这里会执行。
    }
    2)、as? 和as! 可以将类型转换为某种类型。
    class Animal {
    }
    class People : Animal{
    
    }
    let people = People();
    let asAnimal = people as? Animal;//现在asAnimal 是 Animal类型了
    
  • Swift提供了两种任意类型。Any 和AnyObject。其中可以将任何类型的变量转为Any,包括方法。而AnyObject可以代表任意一个类实例。其中AnyObject类似与Java的基类Object.

Extensions[扩展]
  • 扩展是Swift提供的新特性。可以为类、结构体、枚举类、协议扩展新的功能,不同于继承,扩展没有继承层级上的关系。可以当作是附加衍生。
  • 可扩展的内容:
    1)、计算性成员变量。
    2)、实例方法与类型方法
    3)、新构造方法
    4)、下标
    5)、实现协议
  • 扩展语法。
    1)、extension SomeType : Protocol1,Protocol2{
    //添加扩展内容
    }
    2)、实例。为Double添加类型扩展。
    extension Double{
    var km:Double{return self* 1000_0.0}//
    }
    let onInch = 25.6.km;//km是新扩展的计算成员变量。
    
Protocols[协议]
  • 协议与Java中接口的概念是一致的。Swift协议中定义了包括方法、成员变量、类型变量的蓝图。与Java接口不同的是,协议不但可以定义方法,还可以定义成员变量。
  • 协议声明与实现:
    //协议语法
     protocol Nametocol : class{.//如果添加了 class关键字,说明该协议只可以被类实现。
        var fullName :String {get }
        statc func someType();//类型变量,也就是Java的静态变量
        func someMethod();
        mutating func toggle();//可更改内部变量值的方法
        init()//初始化方法
       //可选实现。通过添加@objct optional 关键字修饰,     该方法可以不实现。
        @objc optional func optionalMethod();
    }
    `
    //协议实现
    class MyName :NameProtocol{
    //这里需要实现协议包含的所有内容,区分与Java这里的方法实现不需要添加override关键字
    }
    
Generics [泛型]
  • Swift也提供了泛型,与Java泛型相似。
Access Control [访问控制]
  • Swift也提供了访问控制功能。有模块和文件两类访问控制。
  • 导入模块。通过import 关键字可以导入并使用该模块功能。与Java类似。
  • Swift提供了四种等级的访问控制。分别是public ,internal,fileprivate,private。
    • public.public定义的实体可以在自己的模块内被访问,另外其他模块如果导入了该模块,那么其他模块也可以访问该实体。
  • internal.internal定义的实体可以在自己的模块内被访问。
  • fileprivate。fileprivate定义的实体只能在该文件内被访问。
  • private.private定义的实体只能在该实体里面被访问。
  • Swift访问控制规则:一个被定义为低访问控制的实体,不能声明为高访问控制等级的任何实例。实体包括变量方法等。。
    • 例如定义了一个internal等级的ClassA,不能被声明为 public let classA :ClassA.
    • 一个方法的参数和返回值类型定义的访问权限,一定要大于或者等于该方法被声明时候的权限控制等级。
    • 跟Java一样,继承后重写的方法不能比父类的方法控制权限大。
  • Swift默认为每个实体添加了访问控制:internal.
posted @ 2017-12-15 11:05  Zhouztashin  阅读(189)  评论(0编辑  收藏  举报