美文网首页Swift
1.02类型和操作

1.02类型和操作

作者: Jimmy_L_Wang | 来源:发表于2019-06-13 17:12 被阅读0次

    类型转换

    您需要显式地表示要转换类型,而不是简单地赋值。

    var integer: Int = 100;
    var decimal: Double = 12.5;
    integer = Int(decimal); //swift类型转换需要显示声明
    

    在本例中,将decimal值赋给integer会导致精度下降:integer变量的值最终是12,而不是12.5。这就是为什么需要显示地进行转换的原因。Swift希望确保您知道自己在做什么,并且您可能会因为执行类型转换而丢失数据。

    混合类型运算符

    let hourlyRate: Double = 19.5;
    let hoursWorked: Int = 10;
    let totalCost: Double = hourlyRate * Double(hoursWorked); //195
    

    在本例中,您希望结果是Double。您不需要Int,因为在这种情况下,Swift会将hourlyRate常量转换成Int来执行乘法,将其四舍五入到19,从而失去了Double的精度。

    类型推导 Type inference

    事实证明,Swift编译器也可以推导出变量的类型。它不需要你一直告诉它类型——它可以自己算出来。这是通过一个称为类型推导的过程完成的。

    let typeInferredInt = 42
    

    如果想声明一个Double类型的变量,现在你有4中方式:

    let actuallyDouble = 3.0
    let actuallyDouble = Double(3)
    let actuallyDouble: Double = 3
    let actuallyDouble = 3 as Double
    

    像3这样的文字值没有类型。只有在表达式中使用它们或将它们赋值给常量或变量时,Swift才会推导出它们的类型。

    字符串

    计算机如何表示字符串

    计算机认为字符串是单个字符的集合。在本书的第一章中,您了解到数字是cpu的语言,所有代码,无论使用哪种编程语言,都可以简化为原始数字。字符串也一样。

    这听起来可能很奇怪。字符怎么会是数字呢?在它的基础上,计算机需要能够将一个字符翻译成计算机自己的语言,它通过给每个字符分配不同的数字来做到这一点。这形成了从字符到数字的双向映射,称为字符集。

    当你按键盘上的一个字符键时,你实际上是在把字符的号码与计算机通信。您的文字处理器应用程序将该数字转换为字符的图片,最后将该图片呈现给您。

    swift中的字符串

    字符与字符串

    let characterA: Character = "a"
    let characterDog: Character = "🐶 " //字符不能采用类型推导
    
    let stringDog: String = "Dog"
    let stringDog = "Dog" //字符串推导
    

    在Swift中没有字符语义( character literal )这样的东西。字符就是长度为1的字符串。然而,Swift推断任何字符串语义的类型都是字符串,所以如果您想要一个字符,您必须使用显式类型表达。

    字符串拼接Concatenation

    var message = "Hello" + " my name is "
    let name = "Matt"
    message += name // "Hello my name is Matt"
    

    还可以向字符串添加字符。然而,Swift对类型的严格要求意味着,在这样做时必须显式,就像处理数字时必须显式一样。

    let exclamationMark: Character = "!"
    message += String(exclamationMark) // "Hello my name is Matt!"
    

    字符串插值interpolation

    message = "Hello my name is \(name)!" // "Hello my name is Matt!"
    
     let oneThird = 1.0 / 3.0
    let oneThirdLongString = "One third is \(oneThird) as a decimal." //One third is 0.3333333333333333 as a decimal.
    

    当然,要用无限个字符来表示三分之一的小数,因为这是一个循环小数。双精度字符串插值无法控制得到的字符串的精度。这是使用字符串插值的一个不幸结果:它使用起来很简单,但是没有提供定制输出的功能。

    字符串格式化输出

    print(String(format:"%.1fkg,%03d 个,%@ boy, %@ girl",float, num, string, string)) 
    ///输出结果:1.1kg,010 个,lazy boy, lazy girl
    

    多行字符串

    let bigString = """
      You can have a string
      that contains multiple
      lines
      by
      doing this.
      """
    print(bigString)
    //You can have a string
    //that contains multiple
    //lines
    //by
    //doing this.
    

    请注意,多行字符串文字中的两空间空白被从结果中删除。Swift查看了最后三行双引号中前导空格的数量。使用这个作为基线,Swift要求它上面的所有行至少有那么大的空间,这样它就可以从每一行中删除它。这使您可以使用漂亮的缩进来格式化代码,而不影响输出。

    元祖-Tuples

    有时数据是成对或三个一组的。这方面的一个例子是二维网格上的一对(x, y)坐标。类似地,三维网格上的一组坐标由x值、y值和z值组成。在Swift中,您可以通过使用tuple以非常简单的方式表示此类相关数据。

    元组是一种类型,它表示由任意类型的多个值组成的数据。您可以在元组中拥有任意多的值。例如,可以定义一对二维坐标,其中每个轴值都是整数,如下所示:

    let coordinates: (Int, Int) = (2, 3)
    let coordinates = (2, 3) //类型推导
    

    coordinates的类型是(Int, Int)。元组中的值类型(在本例中为Int)由逗号分隔,并由圆括号包围。创建元组的代码基本相同,每个值由逗号分隔,并由圆括号包围。

    当然不同类型混合也是可以的:

    let coordinatesMixed = (2.1, 3);
    

    如何访问元组中的数据

    您可以通过元组中的位置引用每个项,从0开始。

    let x1 = coordinates.0
    let y1 = coordinates.1
    

    在前面的示例中,索引0处的第一个值是x坐标,索引1处的第二个值是y坐标,这一点可能不是很明显。这是另一个说明为什么总是以避免混淆的方式命名变量很重要的例子。

    幸运的是,允许您为元组的各个部分命名,并且您可以明确表示每个部分代表什么。例如:

     let coordinatesNamed = (x: 2, y: 3)
    // 推导出的类型是 (x: Int, y: Int)
    

    这里,代码注释coordinatesNamed的值,以包含元组每个部分的标签。

    然后,当你需要访问元组的每个部分时,你可以通过它的名字访问它:

    let x2 = coordinatesNamed.x
    let y2 = coordinatesNamed.y
    

    这更清晰,更容易理解。通常,命名元组的组件是有帮助的。

    如果你想同时访问元组的多个部分,就像上面的例子一样,你也可以使用一个简写语法来简化:

    let coordinates3D = (x: 2, y: 3, z: 1)
    let (x3, y3, z3) = coordinates3D
    

    这将声明三个新的常量x3、y3和z3,并依次将元组的每个部分分配给它们。上面的代码等同于:

    let coordinates3D = (x: 2, y: 3, z: 1)
    let x3 = coordinates3D.x
    let y3 = coordinates3D.y
    let z3 = coordinates3D.z
    

    如果想忽略元组的某个元素,可以用下划线替换声明的相应部分。例如,如果您正在执行一个2D计算,并且想忽略coordinates3D的z坐标,那么您可以编写如下代码:

    let (x4, y4, _) = coordinates3D
    

    这行代码只声明了x4和y4。_是特殊的,表示你现在忽略了这部分。

    其他的数字类型

    你一直用Int来表示整数。Int在大多数现代硬件上用64位表示,在较老的或资源受限的系统上用32位表示。Swift提供了更多使用不同存储量的数字类型。对于整数,可以使用显式符号类型Int8Int16Int32Int64。这些类型分别消耗1、2、4和8字节的存储空间。每一种类型都使用1位bit来表示符号sign类型。

    如果只处理非负值,则可以使用一组显式无符号unsigned类型。这些包括UInt8UInt16UInt32UInt64。虽然不能用这些符号表示负值,但是额外的1位bit可以表示比带符号signed的值大两倍的值。

    下面是不同整数类型及其存储大小(以字节为单位)的总结。大多数情况下,您只需要使用Int

    如果您的代码与另一个使用这些更精确的大小的软件片段交互,或者您需要优化存储大小,那么这些代码将非常有用。

    number_values.png

    你一直在用Double表示小数。Swift提供了一种Float类型,它的范围和精度都只是Double的一半,但需要的存储空间也只需要一半。现代硬件已经为Double进行了优化,所以它应该是您的首选,除非有充分的理由使用Float

    float_double.png

    大多数情况下,您将只使用Int和Double来表示数字,但是您可能偶尔会遇到其他类型。

    例如,假设您需要将一个Int16、一个UInt8和一个Int32相加。你可以这样做:

    let a: Int16 = 12
    let b: UInt8 = 255
    let c: Int32 = -100000
    let answer = Int(a) + Int(b) + Int(c)  //结果是Int
    

    协议简介

    尽管有十几种不同的数字类型,但它们都非常容易理解和使用,因为它们基本上都支持相同的操作。换句话说,一旦您知道如何使用Int,使用其他的任何一种都很容易。

    Swift真正伟大的特性之一是,它使用所谓的协议将类型通用性的概念形式化。通过学习协议,您可以立即了解使用该协议的整个类型家族是如何工作的。

    protocol_numeric.png

    箭头表示符合(有时称为采用)协议。虽然这个图没有显示整数类型遵循的所有协议,但是它让您了解了事物是如何组织的。

    Swift是第一种基于协议的语言。当您开始理解类型背后的协议时,您可以使用其他语言无法使用的方式来利用系统。

    翻译自Raywenderlich的Swift书籍Swift Apprentice

    相关文章

      网友评论

        本文标题:1.02类型和操作

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