美文网首页ios 开发iOS安安IOS
Swift 十二讲 第二章 常量变量类型元组字符串和操作符

Swift 十二讲 第二章 常量变量类型元组字符串和操作符

作者: zydscience | 来源:发表于2015-01-30 13:11 被阅读465次

    (Draft)

    1. 类型,常量,变量

    • 数值类型

    Swift包含各种常见数据类型。例如各种有无符号的32位,64位整数,浮点数,布尔数等等。数据类型的max,min属性用来报告数据类型的最大最小区间。例如:

    Int.max 
    //Playground里显示答案:9,223,372,036,854,775,807
    

    0b,0o,0x分别用来表示二进制,八进制,十六进制数。Swift也支持1.2e4这样的缩写。详细细节可以参考官方手册。

    • Swift支持Character和String类型。但不区分字母和单字母的字符串。这两种类型都要用双引号。例如:

        var aa : String = "小狗"
        var bb: Character = "A"
      
    • Swift可以给类型起个直观的别名,然后方便使用。例如

        typealias 短整数 = UInt8
        var cc : 短整数 = 105 
        //注意不要使用中文输入法里的等号;注意别忘了等号前后的空格
    

    上面这段代码,用关键字typealias定义了一个“短整数”类型别名。然后定义了一个变量cc,其类型为“短整数”。cc被初始化为数值105。

    2.变量和常量

    • 在使用一个变量或者常量之前,你必须声明它们。比较下面三种变量声明然后初始化的方法:
    var a = 1
    var a: Int = 1
    

    或者

    var a: Int
    a=1
    

    很显然,最好用的是var a=1。 Swift会自行推断类型。注意,初始化不是必须的。上面例子是为了说明简洁。
    变量用var关键字。常量用let关键字。例如:

    let k = 1
    let kk : Float = 3.14
    

    常量不能被改变。所以它在声明的时候,必须被赋值。如上面的例子所示,常量的类型推断使用起来也非常方便。

    • 除了上面和其他语言类似的变量声明之外,你还可以声明计算变量。如下例子:
    var ax : Int
    {return 20}
    ax+ax //Playground显示结果为40
    

    你还可以在上例的大括号中使用get和set函数。但作者认为这两个函数在这里用处不大。就不展开了。有兴趣的读者可以在Playground试验。

    *willset和didset这两个函数可以在变量被声明的时候附带定义。如果使用变量观测器,变量类型必须被显式指定,而且必须被初始化。如下例:

    var a : Int = 0
    {
    willSet
        {println("a将被赋值")}
    didSet 
    {println("a已经被赋值")}
    }
    
    a = 0 //Playground的console会显示"a将被赋值"和"a已经被赋值"两行字
    

    作者个人认为,计算变量,willSet和didSet是面向对象风格的语言要素。传统语言例如c的变量声明是不包含这些部分的。对变量来说,这三个东西的用处不大,还说不定容易引起混乱。但后面读者会看到。类的属性也使用类似的语法,那里就非常关键了。

    2.元组(Tuples)

    • 不同类型的变量或者常量,加上逗号分隔,加上括号,就构成了元组。元组的声明和初始化方法和变量,常量的风格是一致的。假设你熟悉了变量和常量,那么下面例子,一看就可以懂。
    var a = ("狗", 1, 2.3) //使用类型推断定义了一个元组变量
    println(a.0) //用位置表示元组中的单个元素,console输出为“狗”
    

    你也可以用下面方法定义元组。效果是一样的。

    var a : (String, Int, Float)
    a = ("狗", 1, 2.3)
    println(a.0)
    
    • 元组的单个元素还可以有个名字,你可以用名字而不是位置来指出这个元素。
    var a:(动物种类 : String, 年龄 : Int, 毛长 : Float)
    a = ("狗", 1, 2.3)
    println(a.动物种类) 
    //a.0 和 a.动物种类 是同一个元素的名字。后者更直观而已。
    
    • 你可以对元组的类型使用类型别名,也就是关键字typealias
    typealias 动物 = (动物种类 : String, 年龄 : Int, 毛长 : Float)
    var a:动物
    a = ("狗", 1, 2.3)
    println(a.动物种类) 
    
    • 显然,Swift的元组是非常强大的。尤其是在一块程序往另一块程序输入输出信息的时候,元组这个容器可以非常好用。但笔者建议,对结构化数据,尽量用专门的结构化数据类型。专门适用的结构化数据类型可能有性能优势。例如整型数组,你写成元组,肯定性能不是很划算。

    3.操作符

    操作符被用来指明作用于被操作的语言名词上的一些操作。例如加减乘除,绝对值等等。这些定义都和C语言类似。Swift也支持位运算,以及=++,++等操作符。这些常用的操作符,笔者就不抄写手册了。但有以下几点,笔者认为应该特别注意。

    • Overflow operators
      Swift支持溢出加减乘除。例如溢出除法&/:
    println(0&/0) //输出是0。Swift的溢出除法规定被0除返回0
    
    • 类型检查和转换操作符
      Swift支持三种类型检查和转换操作符:
      is被用来检查是否一个instance属于一个指定的类或者协议
      as被用来转换到一个子类或者协议。
      as?可选转换。如果转换失败,返回nil。
      这些内容会在后面详细解释。读者在此知道有这么回事就好。

    • 范围操作符
      (a...b)表示a到b的所有整数,包含a和b。a必须小于或者等于b。

     for i in 1...5
    {
    println(i)
    }   //将输出1,2,3,4,5
    

    也可以用小于号和两个点:

     for i in 1..<6
    {
    println(i)
    }   //将输出1,2,3,4,5
    
    • 分支选择操作符

    expr1? expr_A:expr_B

    上面描述的意思是,如果条件表达式expr1的值为真,则执行expr_A的代码段。不然就执行expr_B。例如:

    var a = 10
    a == 1 ? println(a) : println(-a)
    

    //输出是-10

    4. 字符串的加减,比较,传递和\操作

    • Swift的字符串是实际值类型。每次被传递到一个函数里,都会被复制一份。字符串被传递的不是其地址。

    • 字符串可以做加法。就是把另一个字符串附加到前一个。也可以连加。例如:

    let a = "我是" + "一个" + "好人"
    println(a) //输出为:我是一个好人
    
    • countElements(MyStrings)这个函数用来计算字符串包含的字符数,而不是bytes数。例如
    println(countElements("我是一个好人")) //输出为6
    
    • 字符串的比较

    ==表示字符相等。!=表示不等。如果一个字符串字典序在另一个之前,那么前者为小,例如:

    println("blue"<"dog") //输出为true
    
    println(("好人"<"坏人")) //输出为false。
    //中文字符串的字典序很不直观啊。谁能告诉我为什么好人小于坏人...
    
    • 字符串的前后缀

    字符串有两个内建属性函数: hasPrefix和hasSuffix。
    下面例子可以明确说明字符串前后缀判断函数的用法:

    println(("好人".hasPrefix("好")))  //输出为true
    println(("好人不坏".hasSuffix("坏"))) //输出为true
    
    • Escape符号

    我个人认为,Escape符号在编译器里面的用法,是计算机科学最简单明了,但又最深的部分之一。绝对不要小瞧了它。

    Ken Thmpson的图灵奖讲话:
    http://cm.bell-labs.com/who/ken/trust.html
    This is an amazing piece of code. It "knows" in a completely portable way what character code is compiled for a new line in any character set. The act of knowing then allows it to recompile itself, thus perpetuating the knowledge.

    这个东西的原理很简单,当编译器读到你代码里的一个\的时候,它会再读下一个字符,然后才能决定前一个字符的意思。如果是两个\,那么它的意思就是一个\。如果是\n,因为只有一个,所以它的意思就是\n本身,也就是line feed。

    所以编译器对\的翻译需要两次扫描,第一次先走到\后面的字符,然后再回来决定前一个\的意思。这种两次扫描的办法,是所有编译器最基本的原理的一部分。有了这个办法,你可以逐步扩展你的编译器功能。人常听说"C的编译器是C写的"之类的说法,其根本原理其实就是在于Escape符号的用法。

    • 字符串的插值

    在Swift里,可以用** "\(expr)" **计算expr的值,然后结果被转换为字符串。下面是一些例子:

    println("\(2+3)")  
    println("神奇的Escape=\(2+3)")
    //上句输出是: 神奇的Escape=5
    println("神奇的Escape=\\")
    println("神奇的Escape=\\\(2+3)")
    

    还有一个深入一点的例子:

    let b = 20
    println("\((b == 10) ? 1 : 2)")
    //输出为2
    

    记住** "\(expr)" 是个筐,里面什么都能装。当然,虽然 "\(expr)" **结构简单+原理深刻,多试验有助于理解计算机工作原理。但作者不鼓励这么写。

    相关文章

      网友评论

      • 碧霄问鼎:错别字不少,/*as?可选转换。如果转换失败,返回nail*/。

      本文标题:Swift 十二讲 第二章 常量变量类型元组字符串和操作符

      本文链接:https://www.haomeiwen.com/subject/cwelxttx.html