5.0什么时候出 swift_swift3.0更新到5.0 - CSDN
  • swift5.0 原版文档

    2020-07-17 17:50:49
    TheSwiftProgrammingLanguageSwift5.epub swift5.0 原版文档
  • Swift5.0新特性更新

    2019-02-12 09:48:13
    原文博客地址: Swift 5.0新特性更新 期待已久的Swift 5.0终于来啦, Swift 5.0Swift中最备受关注的一个版本, 传说中API稳定的版本 随着Xcode Bate 10.2的发布, Swift 5.0也发布了测试版, 相信也带来了很多优化和...

    Swift

    • 原文博客地址: Swift 5.0新特性更新
    • 期待已久的Swift 5.0终于来啦, Swift 5.0Swift中最备受关注的一个版本, 传说中ABI稳定的版本
    • 随着Xcode Bate 10.2的发布, Swift 5.0也发布了测试版, 相信也带来了很多优化和改进
    • 下面运行环境都是在Xcode Bate 10.2环境中进行的

    新特性

    dynamicCallable

    • SE-0216
    • @dynamicCallableSwift添加了一个新属性, 允许使用一个简单的语法糖调用函数一样调用命名类型
    • 如果需要添加@dynamicCallable属性, 就必须要实现以下方法中的一个或者两个
    func dynamicallyCall(withArguments args: [Int]) -> Double
    
    func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Double
    
    • 注意点:
    • 除了接受各种输入外,您还可以为各种输出提供多个重载, 自定义返回值, 可以是String, Int等等…
    • KeyValuePairs的使用和介绍, 没有使用过的可参考

    下面看一个例子, RandomNumberGenerator生成一个随机数

    Swift 5.0之前的定义和调用方式

    // 定义方式
    struct RandomNumberGenerator {
        func generate(numberOfZeroes: Int) -> Double {
            let maximum = pow(10, Double(numberOfZeroes))
            return Double.random(in: 0...maximum)
        }
    }
    
    
    // 调用方式
    let random = RandomNumberGenerator()
    let num = random.generate(numberOfZeroes: 2)
    print(num)
    

    Swift 5.0使用@dynamicCallable属性

    // 定义方式
    @dynamicCallable
    struct RandomNumberGenerator {
        func dynamicallyCall(withArguments args: [Int]) -> Double {
            let numberOfZeroes = Double(args.first ?? 0)
            let maximum = pow(10, numberOfZeroes)
            return Double.random(in: 0...maximum)
        }
    }
    
    
    // 调用方式
    let random = RandomNumberGenerator()
    let num = random(2)
    // random(2)等同于random.dynamicallyCall(withArguments: [2])
    print(num)
    
    • @dynamicCallable使用注意事项
    • 可以将它应用于结构,枚举,类和协议。
    • 如果你实现withKeywordArguments:并且没有实现withArguments:,你仍然可以在没有参数标签的情况下调用
    • 如果你的实现withKeywordArguments:withArguments:时标记为throw,则调用该类型也将被抛出throw
    • 扩展名无法添加@dynamicCallable,只能添加到主要类型上
    • 仍然可以为你定义的类型添加其他方法和属性,并且能够正常使用

    WritableKeyPath

    • SE-0227
    • 添加引用标识键路径的功能,该路径指的是应用它的整个输入值
    • Swift中的每个值都有一个特殊的伪属性.self,它指的是整个值
    let id = \Int.self  
    var x = 1
    print(id)   ////Swift.WritableKeyPath<Swift.Int, Swift.Int>
    x.self = 2
    print(x)   //2
    print(x.self)  //2
    
    print(x[keyPath: id])  //2
    x[keyPath: id] = 3
    print(x[keyPath: id])  //3
    

    可选参数

    Swift 5之前,可以编写一个带有可变参数的枚举, 但是在Swift 5开始, 调用时会报错, 如下

    enum X {
        // 此处定义切没有调用时不会报错
        case foo(bar: Int...) 
    }
    
    func baz() -> X {
        // 此处调用时会报错
        return .foo(bar: 0, 1, 2, 3) 
    } 
    

    Swift 5之后, 上述定义改成数组参数, 而不是可变参数, 如下

    enum X {
        case foo(bar: [Int]) 
    } 
    
    func baz() -> X {
        return .foo(bar: [0, 1, 2, 3]) 
    } 
    

    Raw Strings

    \处理

    • SE-0200增加了创建原始字符串的功能,其中反斜杠和引号被解释为文字符号,而不是转义字符或字符串终止符
    • 单行字符串文字可以用反斜杠填充, 以保证原字符串, 否则会报错
    // 文字引用类型
    // 错误写法
    let quote = "Alice: "How long is forever?" White Rabbit: "Sometimes, just one second.""
    // 正确写法
    let quote1 = "Alice: \"How long is forever?\" White Rabbit: \"Sometimes, just one second.\""
    
    
    // 正则表法式类型
    // 错误写法
    let ucCaseCheck = "enum\s+.+\{.*case\s+[:upper:]"
    // 正确写法
    let ucCaseCheck = "enum\\s+.+\\{.*case\\s+[:upper:]"
    

    #处理

    • 要使用原始字符串, 可使用#将字符串包裹起来
    • #字符串开头和结尾的符号成为字符串分隔符的一部分,因此如下Swift理解“rain”“Spain”周围的独立引号应该被视为文字引号而不是结束字符串
    • 原始字符串也允许使用反斜杠, 但是将反斜杠视为字符串中的文字字符,而不是转义字符
    let rain = #"The "rain" in "Spain" falls mainly on the Spaniards."#
    
    let keypaths = #"Swift keypaths such as \Person.name hold uninvoked references to properties."#
    
    let answer = 42
    let dontpanic = #"The answer to life, the universe, and everything is \#(answer)."#
    

    注意: 上面使用\#(answer)引用变量而不是\(answer), 因为在用#包裹的字符串中反斜杠将会被失败别为文字字符而不是转义字符, 所以必须额外的添加#

    ##处理

    • 在字符串的开头和结尾使用#处理, 在字符串中可以使用反斜杠等特殊字符, 那如果字符串中需要使用#, 又该如何处理??
    • 使用#包裹字符串, 默认会以#为字符串的结束符号, #后面的文字将不再处理, 在这种情况下, 我们会使用##处理
    • 注意: 字符串的开头和结尾的标识必须一样
    let str = ##"My dog said "woof"#gooddog"##
    
    

    多行字符串

    原始字符串与Swift的多行字符串系统完全兼容 - 只需用于#"""启动,然后"""#结束

    let multiline = #"""
        The answer to life,
        the universe,
        and everything is \#(answer).
        """#
    

    try?嵌套

    先看下面代码

    struct User {
        var id: Int
    
        init?(id: Int) {
            if id < 1 {
                return nil
            }
    
            self.id = id
        }
    
        func getMessages() throws -> String {
            // complicated code here
            return "No messages"
        }
    }
    

    Swift4.2及其之前的版本中

    let user = User(id: 1)
    // 这里得到的message的类型是: let messages: String??
    let messages = try? user?.getMessages()
    
    // 如果我们想得到非可选值就需要
    print((messages ?? "") ?? "")
    // 或者多次强解, 当然不建议强解写法
    print(messages!!)
    
    • Swift4.2及其之前的版本中, 上面返回的是一个2层嵌套的可选值, 如果有多层嵌套处理起来也是相当更麻烦的
    • Swift 5中就完美的解决了这个问题, 如果当前值是可选的, 那么try?将不会将值包装在可选值中, 因此最终结果只是一个String?
    • 因此在Swift 5中无论有多少可嵌套的可选最后, 返回值永远只是一个可选值
    • 同样,如果你使用了可选的链接as?,你仍然只有一个级别的可选性
    let user = User(id: 1)
    // 类型: let messages: String?
    let messages = try? user?.getMessages()
    
    print(messages ?? "")
    

    isMultiple

    • SE-0225为整数类型添加了一个方法isMultiple
    • 该方法可以检查一个证书是否为另一个整数的倍数
    let rowNumber = 4
    
    if rowNumber.isMultiple(of: 2) {
        print("Even")
    } else {
        print("Odd")
    }
    
    // 该方法等效于
    if rowNumber % 2 == 0 {}
    

    count

    • SE-0220
    • Swift之前的版本中, 有一个函数filter可以过滤出数组中符合条件的的元素, 组成一个新的数组, 详细使用可参考Swift函数式编程之高级用法
    • Swift 5中新增了一个函数count(where:), 可以获取数组中符合条件的元素的个数
    let arr = [1, 2, 34, 5, 6, 7, 8, 12, 45, 6, 9]
    
    let filter = arr.filter({ $0 > 10 })
    print(filter)  //[34, 12, 45]
    
    let count = arr.count(where: { $0 > 10 })
    print(count)  // 3
    

    compactMapValues

    • Swift4.x的版本有两个函数compactMapmapValues
    • compactMap: 返回一个操作后得到的新的数组, 类似flatMap
    • mapValues: 字典中的函数, 对字典的value值执行操作, 返回改变value后的新的字典
    let times = [
        "first": 2,
        "second": 43,
        "three": 12,
        "four": 3
    ]
    
    let compact = times.compactMap({ $0.value > 10 })
    print(compact)
    // [true, false, true, false]
    
    let mapValues = times.mapValues({ $0 + 2 })
    print(mapValues)
    // ["second": 45, "first": 4, "three": 14, "four": 5]
    
    • SE-0218Swift 5中新增了一个函数compactMapValues
    • compactMapValues是将上述两个方法的功能合并在一起, 返回一个对value操作后的新字典, 并且自动过滤不符合条件的键值对
    let times1 = [
        "Hudson": "38",
        "Clarke": "42",
        "Robinson": "35",
        "Hartis": "DNF"
    ]
    
    let comMap2 = times1.compactMapValues({ Int($0) })
    print(comMap2)
    // ["Clarke": 42, "Robinson": 35, "Hudson": 38]
    

    SubSequence

    • Sequence协议不再具有SubSequence关联类型。先前返回SubSequenceSequence方法现在会返回具体类型
    • 使用SubSequenceSequence扩展应该修改为类似地使用具体类型,或者修改为Collection的扩展,在CollectionSubSequence仍然可用
    // swift 5不在支持
    extension Sequence {
        func dropTwo() -> SubSequence {
            return self.dropFirst(2)
        }
    }
    
    
    // 建议改为
    extension Sequence {
        func dropTwo() -> DropFirstSequence<Self> { 
            return self.dropFirst(2)
        }
    }
    
    // 或者
    extension Collection {
        func dropTwo() -> SubSequence {
            return self.dropFirst(2)
        }
    }
    

    其他相关更新

    SE-0214

    DictionaryLiteral类型重命名为KeyValuePairs

    SE-0238

    • 在使用Swift 5软件包管理器时,Targets可以声明一些常用的针对特定目标的build settings设置
    • 新设置也可以基于平台和构建配置进行条件化处理。包含的构建设置支持SwiftC语言定义,C语言头文件搜索路径,链接库和链接框架

    SE- 0236

    • 在使用Swift 5时, 可以自定义所支持的最低版本号, 如果该项目的依赖包所支持的最低版本大于项目的最低版本号, 则项目会报错

    SR-695

    Swift 5中不再支持返回Self的类方法

    // 不在支持
    class Base { 
        class func factory() -> Self { /*...*/ }
    } 
    

    SR-631

    不同文件中的扩展名无法相互识别

    class FirstClass { }
    
    extension FirstClass {
        class SecondClass { }
    }
    
    // 这里将会报错: "SecondClass is not a member type of FirstClass"
    extension FirstClass.SecondClass { 
        class ThirdClass { }
    }
    

    SR-7251

    Swift 5中, 在所声明的类里面, 所声明的变量名不能和类名一样

    struct S {}
    extension S {
      static var i: Int { return 0 }
      struct i {} // error: “i”的声明无效
    }
    
    // 下面的方式是没有问题的
    struct S1<T> {}
    extension S1 {
      static var i: Int { return 0 }
      struct i {} // This is fine!
    }
    

    参考文献


    展开全文
  • Swift 5.0 -- About Swift

    2019-02-13 18:03:05
    时隔半年之久,项目缠身,没能督促自己跟进Swift,一转眼已是5.0,带着问题来学习吧。The Swift Programming Language(Swift 5.0) 这里是OC与Swift对比之下提出的问题,之后会陆续找到答案的: 文档里说,Swift...

    时隔半年之久,项目缠身,没能督促自己跟进Swift,一转眼已是5.0,带着问题来学习吧。
    The Swift Programming Language(Swift 5.0)

    这里是OC与Swift对比之下提出的问题,之后会陆续找到答案的:

    文档里说,Swift通过采用现代编程模式来定义大类常见的编程错误:

    • 变量在使用之前要被初始化 

      Q:OC有这个特性吗?
      A:OC没有要求,使用之前一定要初始化.不过个人建议先初始化后再使用,初始化后,指针所指向的空间有了,对象也存在了.
      如果想要了解变量初始化的意义,可以参考文章:iOS中定义变量是否初始化的区别
    • 检查数组是否越界
    • 检查整数是否溢出

      Q:OC是否可以编译时检查数组是否越界?
      A:OC是动态语言,只会在运行时才知道数组是否越界,没有预知能力,所以swift更安全
    • 可选值(Optionals) 确保nil 明确地被处理过

      Q: OC可以处理nil值吗?
      A:若不做任何保护代码判断,OC 是没有能力自行判断的
    • 自动管理内存

      Q:OC的内存自动管理机制和Swift有什么不同吗?
      A:Swift使用自动引用计数(ARC)来简化内存管理,与OC一致
    • 错误处理允许从异常失败中控制恢复。

      Q: OC可以做到吗?
      A:目前还没听说,异常失败后就app就退出了,需要重启,Swift如何做到,有待继续学习.

     

     

    参考文章:iOS中定义变量是否初始化的区别

    展开全文
  • Swift是iOS,macOS,watchOS和tvOS应用程序开发的新编程语言。尽管如此,Swift的许多部分对您在C和Objective-C中的开发经验都很熟悉。 2. Swift的基本类型 2.1提供了自己的所有基本C和OC类型的版本,Int为整数...

    1.基础部分

    • 前言

    1. Swift应用场景

    Swift是iOS,macOS,watchOS和tvOS应用程序开发的新编程语言。尽管如此,Swift的许多部分对您在C和Objective-C中的开发经验都很熟悉。

    2. Swift的基本类型
    2.1 提供了自己的所有基本C和OC类型的版本,
    Int为整数
    DoubleFloat为浮点值
    Bool布尔值
    String为文本数据
    2.2 Swift还提供了三种主要类型的集合强大的版本:集合类型
    Array
    Set
    Dictionary

    3. 常量和变量
    与C一样,Swift使用变量来存储和通过标识名称引用值。
    Swift还广泛使用其值无法更改的变量。这些被称为常量,并且比C中的常量更强大。
    当您使用不需要更改的值时,在整个Swift中使用常量来使代码更安全,更清晰。

    4.特有类型
    4.1 元组 (
    tuples)
    除熟悉的类型外,Swift还引入了OC中没有的高级类型,例如元组。
    元组使您可以创建和传递值的分组。你可以使用元组将函数中的多个值作为单个复合值返回

    4.2 可选类型(optional types)
    Swift还引入了可选类型,它们处理缺少值。选配说要么“有一个值,它等于X ”或“没有任何值”。
    使用optionals类似于使用OC里的nil做指针,但它们适用于任何类型,而不仅仅是类。
    它们不仅比nilObjective-C中的指针更安全,更具表现力,它们是Swift许多最强大功能的核心。

    5. 类型安全 (type-safe)
    Swift是一种类型安全的语言,这意味着该语言可以帮助您清楚代码可以使用的值的类型。
    如果您的部分代码需要一个 String类型,则类型安全会阻止您Int错误地传递它。
    同样,类型安全性可防止您意外地将可选项传递String给需要非可选值的String
    类型安全性(
    Type safety)可帮助您在开发过程中尽早捕获并修复错误

    • 正文

    1. 常量和变量

    常量和变量将名称(例如maximumNumberOfLoginAttemptswelcomeMessage)与特定类型的值(例如数字10或字符串"Hello")相关联。
    常量的值一旦设置就不能更改,而变量可以在将来设置为不同的值。

    1.1 声明常量和变量

    1.1.1    必须在使用之前声明。
    1.1.2   用let声明常量,用var声明变量。
    下面是一个示例,说明如何使用常量和变量来跟踪用户进行的登录尝试次数:

    let maximumNumberOfLoginAttempts = 10
    var currentLoginAttempt = 0

    此代码可以读作:

    “声明一个新的常量调用maximumNumberOfLoginAttempts,并给它一个值10。然后,声明一个名为的新变量currentLoginAttempt,并给它一个初始值0。“

    在此示例中,允许的最大登录尝试次数被声明为常量,因为最大值永远不会更改。当前登录尝试计数器被声明为变量,因为在每次登录尝试失败后,此值必须递增。

    1.1.3 你也可以在一行上声明多个常量或多个变量,用逗号分隔:

    var x = 0.0, y = 0.0, z = 0.0
    /*注意
    
    如果代码中的存储值不会更改,请始终使用let关键字将其声明为常量。仅使用变量存储需要更改的值。*/

     

    1.2 类型注释

    1.2.1
    声明常量或变量时,可以提供类型注释,以清楚常量或变量可以存储的值的类型。
    通过在常量或变量名称后面放置冒号,后跟空格,后跟要使用的类型的名称来编写类型注释。

    此示例为名为变量的变量提供类型注释welcomeMessage,以指示变量可以存储String值:

    var welcomeMessage: String

    声明中的冒号表示“......类型......”,因此上面的代码可以解读为:“声明一个名为welcomeMessagetype 的变量String。”

    短语“类型String”的意思是“可以存储任何String值。”将其视为可以存储的“事物的类型”(或“那种事物”)。

    welcomeMessage现在可以将变量设置为任何字符串值而不会出现错误:

    welcomeMessage = "Hello"

    1.2.2 可以在一行上定义相同类型的多个相关变量(以逗号分隔),在最终变量名称后面使用单个类型注释:

    var red, green, blue: Double
    /*注意
    您很少需要在实践中编写类型注释。
    如果在定义的点处为常量或变量提供初始值,
    则Swift几乎总是可以推断出用于该常量或变量的类型,如类型安全和类型推断中所述。
    在welcomeMessage上面的示例中,没有提供初始值,
    因此welcomeMessage使用类型注释指定变量的类型,而不是从初始值推断。
    */

     

    1.3 命名常量和变量

    常量和变量名称几乎可以包含任何字符,包括Unicode字符:

    let π = 3.14159
    let 你好 = "你好世界"
    let ?? = "dogcow"

    ⚠️常量和变量名称不能包含空格字符,数学符号,箭头,专用Unicode标量值或行和框绘制字符。
    ⚠️它们也不能以数字开头,尽管数字可能包含在名称的其他地方。
    ⚠️一旦声明了某个类型的常量或变量,就不能再使用相同的名称声明它,或者将其更改为存储不同类型的值。也不能将常量变为变量或变量变为常量。

    ⚠️如果您需要为常量或变量提供与保留的Swift关键字相同的名称,请在将关键字`用作名称时用backticks()包围该关键字。但是,除非您绝对没有选择,否则请避免使用关键字作为名称。

    你可以将现有变量的值更改为兼容类型的另一个值。
    在此示例中,值的值friendlyWelcome更改"Hello!""Bonjour!"

    var friendlyWelcome = "Hello!"
    friendlyWelcome = "Bonjour!"
    // friendlyWelcome is now "Bonjour!"

    与变量不同,常量的值在设置后不能更改。编译代码时,尝试执行此操作会报告为错误:

    let languageName = "Swift"
    languageName = "Swift++"
    // This is a compile-time error: languageName cannot be changed.

    1.4 打印常数和变量

    1.4.1 你可以使用以下print(_:separator:terminator:)函数打印常量或变量的当前值:

    print(friendlyWelcome)
    // Prints "Bonjour!"

    print(_:separator:terminator:)函数是一个全局函数,它将一个或多个值输出到适当的输出。
    例如,在Xcode中,该print(_:separator:terminator:)函数在Xcode的“控制台”窗格中打印其输出。该separatorterminator参数都有默认值,所以当你调用这个函数,你可以忽略它们。
    默认情况下,该函数通过添加换行符来终止它打印的行。要在其后打印没有换行符的值,请将空字符串作为终止符传递 - 例如,。有关具有默认值的参数的信息,请参阅默认参数值print(someValue, terminator: "")

    1.4.2
     Swift使用字符串插值将常量或变量的名称包含在较长字符串中作为占位符,并提示Swift将其替换为该常量或变量的当前值。将名称括在括号中,并在左括号前用反斜杠转义它:

    print("The current value of friendlyWelcome is \(friendlyWelcome)")
    // Prints "The current value of friendlyWelcome is Bonjour!"
    
    /*注意
    
    你可以用串插中使用的所有选项中描述字符串插值。*/

    评论(Comments)

    使用注释在代码中包含不可执行文本,作为对自己的注释或提醒。编译代码时,Swift编译器会忽略注释。

    2.1 Swift中的注释与C中的注释非常相似。单行注释以两个正斜杠开头(//):

    // This is a comment.

    2.2 多行注释以正斜杠开头,后跟星号(/*),以星号后跟正斜杠(*/)结束:

    /* This is also a comment
    but is written over multiple lines. */

    2.3 与C中的多行注释不同,Swift中的多行注释可以嵌套在其他多行注释中。您可以通过启动多行注释块然后在第一个块中开始第二个多行注释来编写嵌套注释。然后关闭第二个块,然后是第一个块:

    /* This is the start of the first multiline comment.
    /* This is the second, nested multiline comment. */
    This is the end of the first multiline comment. */

    嵌套的多行注释使您可以快速轻松地注释掉大块代码,即使代码已经包含多行注释。

    3. 分号(Semicolons)
    与许多其他语言不同,Swift不要求您;在代码中的每个语句之后编写分号(),但如果您愿意,也可以这样做。
    但是,如果要在一行上写多个单独的语句,需要使用分号:

    let cat = "?"; print(cat)
    // Prints "?"

    4.整型(Integers

    整数整数,没有小数分量,例如42-23
    整数有符号(正,零或负)或无符号(正或零)。

    Swift提供8,16,32和64位格式的有符号无符号整数。这些整数遵循类似于C的命名约定,
    8位无符号整数属于类型UInt8
    32位有符号整数属于类型Int32
    与Swift中的所有类型一样,这些整数类型具有大写的名称

    4.1 整数界限

    你可以用它来访问每个整数类型的最小值和最大值minmax特性:

    let minValue = UInt8.min // minValue is equal to 0, and is of type UInt8
    let maxValue = UInt8.max // maxValue is equal to 255, and is of type UInt8

    这些属性的值具有适当大小的数字类型(例如UInt8在上面的示例中),因此可以在表达式中与其他相同类型的值一起使用。

    Int
    在大多数情况下,您不需要选择要在代码中使用的特定大小的整数。
    Swift提供了一个额外的整数类型,Int它与当前平台的本机字大小相同:

    • 在32位平台上,Int大小与之相同Int32
    • 在64位平台上,Int大小与之相同Int64

    除非您需要使用特定大小的整数,否则请始终Int在代码中使用整数值。这有助于代码一致性和互操作性。即使在32位平台上,Int也可以在-2,147,483,648和之间存储任何值2,147,483,647,并且对于许多整数范围来说足够大。

    UInt
    Swift还提供无符号整数类型,UInt其大小与当前平台的本机字大小相同:

    • 在32位平台上,UInt大小与之相同UInt32
    • 在64位平台上,UInt大小与之相同UInt64

    ⚠️使用UInt只有当你特别需要具有相同大小的平台的本地字大小的无符号整型。如果不是这种情况,Int则优选,即使已知要存储的值是非负的。Int对整数值的一致使用有助于代码互操作性,避免在不同数字类型之间进行转换,并匹配整数类型推断,如类型安全和类型推断中所述

    5.浮点数字 (Floating-Point Numbers

    浮点数是具有小数部分的数字,例如3.141590.1,和-273.15
    浮点类型可以表示比整数类型更宽范围的值,并且可以存储比可以存储在一个更大或更小的数字Int。Swift提供了两种带符号的浮点数类型:

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

    ⚠️Double具有至少15位十进制数的精度,而精度Float可以小至6位十进制数。要使用的适当浮点类型取决于您在代码中使用的值的性质和范围。在任何一种类型适当的情况下,Double首选。

    6.类型安全和类型推断Type Safety and Type Inference
    Swift是一种类型安全的语言。类型安全语言鼓励您清楚代码可以使用的值的类型。
    如果您的部分代码需要一个 String类型,则不能错误地传递Int。

    因为Swift是类型安全的,所以它在编译代码时执行类型检查,并将任何不匹配的类型标记为错误。这使您能够在开发过程中尽早捕获并修复错误。

    当您使用不同类型的值时,类型检查可帮助您避免错误。
    但是,这并不意味着您必须指定您声明的每个常量和变量的类型。
    如果未指定所需的值类型,Swift将使用类型推断来计算出适当的类型。
    类型推断使编译器能够在编译代码时自动推断出特定表达式的类型,只需检查您提供的值即可

    由于类型推断,Swift所需的类型声明远远少于C或OC等语言。
    常量和变量仍然是显式类型的,但指定其类型的大部分工作都是为您完成的。

    当您使用初始值声明常量或变量时,类型推断特别有用。这通常通过在声明它的点处为常量或变量指定文字值(或文字)来完成。(A字面值是直接出现在源代码中,如一个值423.14159在下面的例子。)

    例如,如果您将一个文字值分配42给一个新常量而不说它是什么类型,Swift推断您希望该常量为一个 Int值,因为您已使用看起来像整数的数字初始化它:

    let meaningOfLife = 42
    // meaningOfLife is inferred to be of type Int

    同样,如果您没有为浮点文字指定类型,Swift会推断您要创建一个Double

    let pi = 3.14159
    // pi is inferred to be of type Double

    当推断浮点数的类型时,Swift总是选择Double(而不是Float

    如果在表达式中组合整数和浮点文字,Double将从上下文推断出一种类型:

    let anotherPi = 3 + 0.14159
    // anotherPi is also inferred to be of type Double

    文字值3本身没有明确的类型,因此Double从浮点文字的存在作为加法的一部分推断出适当的输出类型。

    7.数字文字(Numeric Literals

    7.1 整数文字可以写成:

    • 一个十进制数,无前缀
    • 一个二进制数,有0b前缀
    • 一个八进制数,有0o前缀
    • 一个十六进制数,有0x前缀

    所有这些整数文字都有一个十进制值17

    let decimalInteger = 17
    let binaryInteger = 0b10001 // 17 in binary notation
    let octalInteger = 0o21 // 17 in octal notation
    let hexadecimalInteger = 0x11 // 17 in hexadecimal notation

    ⚠️浮点文字可以是十进制(没有前缀)或十六进制(带0x前缀)。
    ⚠️它们必须始终在小数点的两边都有一个数字(或十六进制数字)。
    ⚠️十进制浮点数也可以有一个可选的指数,用大写或小写表示e
    ⚠️十六进制浮点数必须有一个指数,用大写或小写表示p

    对于指数为的十进制数exp,基数乘以10 exp:

    • 1.25e2表示1.25 x 10 2,或125.0
    • 1.25e-2表示1.25 x 10 -2,或0.0125

    对于指数为的十六进制数exp,基数乘以2 exp:

    • 0xFp2指15 x 2 2,或60.0
    • 0xFp-2表示15 x 2 -2,或3.75

    7.2 所有这些浮点文字都有一个十进制值12.1875

    let decimalDouble = 12.1875
    let exponentDouble = 1.21875e1
    let hexadecimalDouble = 0xC.3p0

    7.3 数字文字可以包含额外的格式以使其更易于阅读。整数和浮点数都可以用额外的零填充,并且可以包含下划线以帮助提高可读性。这两种格式都不会影响文字的基础值:

    let paddedDouble = 000123.456
    let oneMillion = 1_000_000
    let justOverOneMillion = 1_000_000.000_000_1

    8.数字类型转换(Numeric Type Conversion

    Int类型用于代码中的所有通用整数常量和变量,即使它们已知为非负。
    在日常情况下使用默认整数类型意味着整数常量和变量可以在代码中立即互操作,并且将匹配整数文字值的推断类型。

    仅在手头任务特别需要时才使用其他整数类型,因为来自外部源的显式大小数据,或性能,内存使用或其他必要的优化。在这些情况下使用显式大小的类型有助于捕获任何意外值溢出并隐式记录所使用数据的性质

    8.1 整数转换

    对于每种数字类型,可以存储在整数常量或变量中的数字范围是不同的。
    一个Int8常数或变量可以存储之间的数字-128127
    UInt8常数或变量可以存储之间的数字0255
    编译代码时,报告的数字不适合大小整数类型的常量或变量:

    let cannotBeNegative: UInt8 = -1
    // UInt8 cannot store negative numbers, and so this will report an error
    let tooBig: Int8 = Int8.max + 1
    // Int8 cannot store a number larger than its maximum value,
    // and so this will also report an error

    由于每种数字类型都可以存储不同的值范围,因此必须根据具体情况选择进行数值类型转换。
    这种选择加入方法可以防止隐藏的转换错误,并有助于在代码中明确显示类型转换意图。

    要将一种特定的数字类型转换为另一种,请使用现有值初始化所需类型的新数字。
    在下面的示例中,常量twoThousand是类型UInt16,而常量one是类型UInt8
    它们不能直接加在一起,因为它们的类型不同。
    相反,此示例调用UInt16(one)创建一个UInt16使用值初始化的新值one,并使用此值代替原始值:

    let twoThousand: UInt16 = 2_000
    let one: UInt8 = 1
    let twoThousandAndOne = twoThousand + UInt16(one)

    因为加号的两侧现在都是类型UInt16,所以允许计算。输出constant(twoThousandAndOne)被推断为类型UInt16,因为它是两个UInt16值的总和。

    SomeType(ofInitialValue)是调用Swift类型的初始值设定项并传入初始值的默认方式。
    在幕后,UInt16有一个接受UInt8值的初始值设定项,因此这个初始化程序用于UInt16从现有的初始化程序中创建一个新的UInt8
    你不能在这里传递任何类型,但它必须是一个UInt16提供初始化器的类型。
    扩展中介绍了扩展现有类型以提供接受新类型(包括您自己的类型定义)的初始化程序
    Extensions

    8.2 整数和浮点转换

    必须明确表示整数和浮点数字类型之间的转换:

    let three = 3
    let pointOneFourOneFiveNine = 0.14159
    let pi = Double(three) + pointOneFourOneFiveNine
    // pi equals 3.14159, and is inferred to be of type Double

    这里,常量的值three用于创建类型的新值Double,以便加号的两侧具有相同的类型。如果没有这种转换,则不允许加法计算。

    浮点到整数转换也必须明确。整数类型可以使用DoubleFloat值初始化:

    let integerPi = Int(pi)
    // integerPi equals 3, and is inferred to be of type Int

    当用于以这种方式初始化新的整数值时,浮点值总是被截断。这意味着,4.75变得4-3.9-3

    ⚠️组合数字常量和变量的规则与数字文字的规则不同。3可以将文字值直接添加到文字值0.14159,因为数字文字本身没有显式类型。它们的类型仅在它们由编译器评估时推断。

    9. 键入别名 (Type Aliases

    类型别名定义现有类型的备用名称。您可以使用typealias关键字定义类型别名。

    当您希望通过上下文更合适的名称引用现有类型时,类型别名非常有用,例如从外部源处理特定大小的数据时:

    typealias AudioSample = UInt16
    

    定义类型别名后,可以在可能使用原始名称的任何位置使用别名:

    var maxAmplitudeFound = AudioSample.min
    // maxAmplitudeFound is now 0

    这里,AudioSample被定义为别名UInt16。因为它是一个别名,调用AudioSample.min实际调用UInt16.min,它提供的初始值0maxAmplitudeFound变量。

    10.布尔(Booleans

    Swift有一个基本的布尔类型,叫做Bool。布尔值被称为逻辑,因为它们只能是true或false。Swift提供了两个布尔常量值,true并且false

    let orangesAreOrange = true
    let turnipsAreDelicious = false

    从使用布尔值初始化它们的事实推断出的类型orangesAreOrangeturnipsAreDelicious推断Bool
    正如上面的IntDouble,如果你将其设置为truefalse,你并不需要声明常量或变量Bool
    类型推断有助于使Swift代码在使用其类型已知的其他值初始化常量或变量时更简洁和可读。

    使用条件语句(如if语句)时,布尔值特别有用:

    if turnipsAreDelicious {
    print("Mmm, tasty turnips!")
    } else {
    print("Eww, turnips are horrible.")
    }
    // Prints "Eww, turnips are horrible."

    控制流程中更详细地介绍了语句等条件语句。

    Swift的类型安全性可防止替换非布尔值Bool。以下示例报告编译时错误:

    let i = 1
    if i {
    // this example will not compile, and will report an error
    }
    

    但是,下面的替代示例是有效的:

    let i = 1
    if i == 1 {
    // this example will compile successfully
    }
    

    比较的结果是类型,因此第二个示例通过了类型检查。
    类似的比较i == 1 在Basic Operators中有讨论。

    与Swift中的其他类型安全示例一样,此方法可避免意外错误,并确保特定代码段的意图始终清晰。

    11.元组(Tuples

    11.1 
    组将多个值分组为单个复合值。
    元组中的值可以是任何类型,并且不必彼此具有相同的类型。

    在此示例中,是一个描述HTTP状态代码的元组。HTTP状态代码是Web服务器在您请求网页时返回的特殊值。如果你请求不存在的网页,则会返回状态代码。
    (404, "Not Found")404 Not Found

    let http404Error = (404, "Not Found")
    // http404Error is of type (Int, String), and equals (404, "Not Found")

    的元组基团一起的和,得到的HTTP状态代码两个独立的值:一个数字和一个人类可读的描述。它可以被描述为“类型元组”。(404, "Not Found")IntString(Int, String)

    11.2 
    你可以从任何类型的排列创建元组,它们可以包含任意数量的不同类型。没有什么可以阻止你拥有一个类型元组,或者你需要的任何其他排列。(Int, Int, Int)(String, Bool)

    您可以元组的内容分解为单独的常量或变量,然后您可以照常访问:

    let (statusCode, statusMessage) = http404Error
    print("The status code is \(statusCode)")
    // Prints "The status code is 404"
    print("The status message is \(statusMessage)")
    // Prints "The status message is Not Found"

    如果你只需要一些元组的值,_当你分解元组时忽略元组的一部分用下划线():

    let (justTheStatusCode, _) = http404Error
    print("The status code is \(justTheStatusCode)")
    // Prints "The status code is 404"

    或者,使用从零开始的索引号访问元组中的各个元素值:

    print("The status code is \(http404Error.0)")
    // Prints "The status code is 404"
    print("The status message is \(http404Error.1)")
    // Prints "The status message is Not Found"

    定义元组时,可以命名元组中的各个元素:

    let http200Status = (statusCode: 200, description: "OK")
    

    如果在元组中命名元素,则可以使用元素名称来访问这些元素的值:

    print("The status code is \(http200Status.statusCode)")
    // Prints "The status code is 200"
    print("The status message is \(http200Status.description)")
    // Prints "The status message is OK"

    元组作为函数的返回值特别有用
    尝试检索网页的函数可能会返回元组类型(Int, String)来描述页面检索的成功或失败。通过返回具有两个不同值的元组,每个值都是不同类型,该函数提供有关其结果的更多有用信息,而不是仅返回单个类型的单个值。
    有关更多信息,请参阅具有多个返回值的函数

    ⚠️元组对临时组的相关值组很有用。它们不适合创建复杂的数据结构。如果您的数据结构可能超出临时范围,则将其建模为类或结构,而不是作为元组。有关更多信息,请参阅结构和类

    12.可选项(Optionals

    可以在可能缺少值的情况下使用选项。可选的代表两种可能性:要么有一个值,你可以解开可选项的访问值,或者不存在值

    ⚠️选项的概念在C或OC中不存在。OC中最接近的是从一个方法返回nil,否则返回一个对象的能力,nil意思是“缺少一个有效的对象。”但是,这只适用于对象 - 它不适用于结构,基本C类型或枚举值。对于这些类型,OC方法通常返回特殊值(例如NSNotFound)以指示缺少值。这种方法假定方法的调用者知道有一个特殊的值来测试并记得检查它。Swift的可选项让你可以指出任何类型都没有值,而不需要特殊的常量。

    这是一个如何使用可选项来应对缺少值的例子。
    Swift的Int类型有一个初始化程序,它试图将String值转换为Int值。但是,并非每个字符串都可以转换为整数。字符串"123"可以转换为数值123,但"hello, world"字符串,没有明显的数值可以转换。

    下面的示例使用初始化程序尝试将一个 String转换为Int

    let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    // convertedNumber is inferred to be of type "Int?", or "optional Int"

    因为初始化程序可能会失败,所以它返回一个可选的 Int,而不是一个Int。可选的Int可写为Int?,而不是Int。问号表示它包含的值是可选的,这意味着它可能包含某个 Int值,或者它可能根本不包含任何值。(它不能包含任何其他内容,例如Bool值或String值。它可以是一个Int,或者它根本就没有值。)

    12.1 空(nil)

    通过为其指定特殊值,将可选变量设置为无值状态nil

    var serverResponseCode: Int? = 404
    // serverResponseCode contains an actual Int value of 404
    serverResponseCode = nil
    // serverResponseCode now contains no value

    ⚠️你不能用nil作为非可选常量和变量。如果代码中的常量或变量需要在某些条件下缺少值,则始终将其声明为相应类型的可选值。如果在不提供默认值的情况下定义可选变量,则会自动为您设置变量为nil

    var surveyAnswer: String?
    // surveyAnswer is automatically set to nil

    ⚠️Swift nil与OC的nil不同。在OC中,nil是一个指向不存在的对象的指针。在Swift中,nil不是指针 - 它缺少某种类型的值。可以将任何类型的选项设置为nil,而不仅仅是对象类型。

    12.1 If声明和强制解包

    您可以使用if语句通过比较可选项来确定可选项是否包含值nil。您可以使用“等于”运算符(==)或“不等于”运算符(!=)执行此比较。

    如果可选项具有值,则认为它“不等于” nil

    if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
    }
    // Prints "convertedNumber contains some integer value."

    一旦确定可选项确实包含值,就可以通过!在可选项名称的末尾添加感叹号()来访问其基础值。感叹号有效地说:“我知道这个选项肯定有价值; 请使用它。“这被称为强制解包可选的值:​​​​​​​

    if convertedNumber != nil {
    print("convertedNumber has an integer value of \(convertedNumber!).")
    }
    // Prints "convertedNumber has an integer value of 123."
    

    有关该if语句的更多信息,请参阅控制流

    ⚠️尝试使用!访问不存在的可选值会触发运行时错误。在使用!强制解包其值之前,请务必确保可选项包含非空值。

    12.2 可选绑定

    您使用可选绑定来确定可选项是否包含值,如果是,则使该值可用作临时常量或变量。可选绑定可与with ifwhile语句一起使用,以检查可选内部的值,并将该值提取为常量或变量,作为单个操作的一部分。if控制流程while中更详细地描述了语句。

    if语句编写可选绑定,如下所示:

    if let constantName = someOptional {
    statements
    }
    

    ​​​​​​​您可以重写possibleNumberOptionals部分以使用可选绑定而不是强制解包:

    if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
    } else {
    print("The string \"\(possibleNumber)\" could not be converted to an integer")
    }
    // Prints "The string "123" has an integer value of 123"

    此代码可以读作:

    “如果Int返回的可选项Int(possibleNumber)包含一个值,则设置一个新的常量,调用可选的包含值actualNumber。”

    如果转换成功,则该actualNumber常量可在if语句的第一个分支中使用。它已经被可选的值内包含的值初始化,因此没有必要使用!后缀来访问它的价值。在此示例中,actualNumber仅用于打印转换结果。

    你可以将常量和变量与可选绑定一起使用。
    如果你想操纵语句actualNumber的第一个if分支中的值,你可以用
    if var actualNumber 代替,然后可选项的包含的值将作为变量而不是常量使用。

    你可以根据需要在单个if语句中包含尽可能多的可选绑定和布尔条件,并以逗号分隔。
    如果可选绑定中的值为nil或任何布尔条件求值为falseif则认为整个语句的条件是false。以下if陈述是等效的:

    if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
          print("\(firstNumber) < \(secondNumber) < 100")
    }
    
    // Prints "4 < 42 < 100"
    if let firstNumber = Int("4") {
          if let secondNumber = Int("42") {
             if firstNumber < secondNumber && secondNumber < 100 {
                 print("\(firstNumber) < \(secondNumber) < 100")
                }
            }
     }
    // Prints "4 < 42 < 100"

    ⚠️if语句中使用可选绑定创建的常量和变量仅在if语句的主体中可用。相反,使用guard语句创建的常量和变量在语句后面的代码行中可用guard,如Early Exit中所述

    12.3 隐含的未包装的选项

    如上所述,选项表示允许常量或变量具有“无值”。可以使用if语句检查Optionals 以查看是否存在值,并且可以使用可选绑定有条件地解包,以访问可选的值(如果存在)。

    有时从程序的结构中可以清楚地看出,在首次设置该值之后,可选项将始终具有值。在这些情况下,每次访问时都不需要检查和解包可选项的值,因为可以安全地假设它始终具有值。

    这些类型的选项被定义为隐式解包的选项。你通过在要使其成为可选的类型之后放置感叹号(String!)而不是问号()来编写隐式展开的可String?选项。

    当在首次定义可选项之后立即确认可选的值存在时,隐式展开的选项很有用,并且可以假定在此后的每个点都存在。Swift中隐式解包选项的主要用途是在类初始化期间,如Unowned References和Implicitly Unwrapped Optional Properties中所述

    隐式展开的可选项是幕后的常规可选项,但也可以像非可选值一样使用,而无需在每次访问时解包可选值。以下示例显示了在将其包装值作为显式访问时,可选字符串与隐式解包的可选字符串之间的行为差​​异String

    let possibleString: String? = "An optional string."
    let forcedString: String = possibleString! // requires an exclamation mark
    let assumedString: String! = "An implicitly unwrapped optional string."
    let implicitString: String = assumedString // no need for an exclamation mark

    你可以想到一个隐式解包的可选项,因为它允许在任何时候自动解包可选项。每次使用时,都不要在可选项的名称后面放置感叹号,而是在声明它时在可选项的类型后面添加一个感叹号。

    ⚠️如果隐式解包的可选项是nil并且您尝试访问其包装值,则会触发运行时错误。结果与在不包含值的普通可选项之后放置感叹号完全相同。

    你仍然可以将隐式解包的可选项视为普通可选项,以检查它是否包含值:

    if assumedString != nil {
    print(assumedString!)
    }
    // Prints "An implicitly unwrapped optional string."

    你还可以使用带有可选绑定的隐式展开的可选项,以在单个语句中检查和解包其值:

    if let definiteString = assumedString {
    print(definiteString)
    }
    // Prints "An implicitly unwrapped optional string."

    ⚠️当变量可能变为nil稍后时,不要使用隐式展开的可选项。如果需要在变量的生命周期内检查值是否为nil,请始终使用普通的可选类型。

    13. 错误处理(Error Handling

    你可用错误处理来响应程序在执行期间可能遇到的错误情况。

    与可以使用值的存在或不存在来传递函数成功或失败的可选项相比,错误处理允许您确定失败的根本原因,并在必要时将错误传播到程序的另一部分。

    当函数遇到错误条件时,它会抛出错误。然后该函数的调用者可以捕获错误并做出适当的响应。

    func canThrowAnError() throws {
    // this function may or may not throw an error
    }

    函数表示它可以通过throws在其声明中包含关键字来引发错误。当您调用可以抛出错误的函数时,您可以将try关键字添加到表达式中。

    Swift会自动将错误传播出当前作用域,直到它们被catch子句处理。

    do {
    try canThrowAnError()
    // no error was thrown
    } catch {
    // an error was thrown
    }

    一个do语句创建一个新的包含范围,允许误差传播到一个或多个catch条款。

    以下是如何使用错误处理来响应不同错误条件的示例:

    func makeASandwich() throws {
    // ...
    }
    do {
    try makeASandwich()
    eatASandwich()
    } catch SandwichError.outOfCleanDishes {
    washDishes()
    } catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
    }

    在此示例中,makeASandwich()如果没有可用的干净菜肴或缺少任何成分,该函数将抛出错误。因为makeASandwich()可以抛出错误,函数调用包含在try表达式中。通过将函数调用包装在do语句中,抛出的任何错误都将传播到提供的catch子句。

    如果没有抛出错误,eatASandwich()则调用该函数。如果抛出错误并且它与SandwichError.outOfCleanDishes大小写匹配,则将washDishes()调用该函数。如果抛出错误并且它与SandwichError.missingIngredients大小写匹配,则buyGroceries(_:)调用该函数,并使用模式[String]捕获的关联值catch

    错误处理中更详细地介绍了抛出,捕获和传播错误。
     

    14.断言和前置条件(Assertions and Preconditions

    断言前置条件是在运行时发生的检查。在执行任何进一步的代码之前,您可以使用它们来确保满足必要条件。如果断言或前置条件中的布尔条件求值为true,则代码执行将照常继续。如果条件评估为false,则程序的当前状态无效; 代码执行结束,你的app终止。

    你使用断言和前置条件来表达你所做的假设以及编码时的期望,因此你可以将它们作为代码的一部分包含在内。断言可帮助您在开发过程中发现错误和错误假设,并且前置条件可帮助您检测生产中的问题。

    除了在运行时验证您的期望之外,断言和前置条件也成为代码中有用的文档形式。与上面的错误处理中讨论的错误条件不同,断言和前置条件不用于可恢复或预期的错误。因为失败的断言或前提条件表明程序状态无效,所以无法捕获失败的断言。

    使用断言和前置条件并不能代替以不可能出现无效条件的方式设计代码。但是,如果发生无效状态,使用它们来强制执行有效数据和状态会导致应用程序以更可预测的方式终止,并有助于使问题更易于调试。一旦检测到无效状态就停止执行也有助于限制由该无效状态造成的损害。

    断言和前置条件之间的区别在于它们的检查时间:断言仅在调试版本中检查,但前置条件在调试和发布版本中都会检查。在发布版本中,不会评估断言中的条件。这意味着您可以在开发过程中使用任意数量的断言,而不会影响生产中的性能。

    14.2 使用断言进行调试

    您可以通过assert(_:_:file:line:)从Swift标准库中调用函数来编写断言。您将此函数传递给一个表达式,该表达式求值为true或者false,如果条件的结果为,则显示一条消息false。例如:

    let age = -3
    assert(age >= 0, "A person's age can't be less than zero.")
    // This assertion fails because -3 is not >= 0.

    在此示例中,如果age >= 0 值为true,则代码执行继续,即,值是否为非负值。如果值为负,如上面的代码所示,age >= 0 值为 false,并且断言失败,终止应用程序。

    你可以省略断言消息 - 例如,它只是重复条件作为散文。

    1. assert(age >= 0)

    如果代码已经检查了条件,则使用该assertionFailure(_:file:line:)函数指示断言失败。例如:

    if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
    } else if age >= 0 {
    print("You can ride the ferris wheel.")
    } else {
    assertionFailure("A person's age can't be less than zero.")
    }

    14.3 执行先决条件

    只要条件可能为false,就使用先决条件,但对于代码继续执行必须确实为真。例如,使用前置条件检查下标是否超出范围,或检查函数是否已传递有效值。

    你通过调用precondition(_:_:file:line:)函数编写一个前提条件。您将此函数传递给一个表达式,该表达式求值为true或者false,如果条件的结果为false,则显示一条消息。例如:

    // In the implementation of a subscript...
    precondition(index > 0, "Index must be greater than zero.")

    您也可以调用该preconditionFailure(_:file:line:)函数来指示发生了故障 - 例如,如果采用了交换机的默认情况,但是所有有效的输入数据应该由交换机的其他情况之一处理。

    ⚠️如果以unchecked mode(-Ounchecked)编译,则不检查前置条件。编译器假定前置条件始终为true,并相应地优化代码。但是,fatalError(_:file:line:)无论优化设置如何,该功能始终会暂停执行。

    您可以在原型设计和早期开发期间使用该功能fatalError(_:file:line:),通过编写fatalError("Unimplemented")存根实现来创建尚未实现的功能的存根。因为致命错误永远不会被优化,与断言或前提条件不同,您可以确保执行始终在遇到存根实现时停止。

     

    展开全文
  • swift正式开源v5.0

    2020-07-15 23:36:10
    Swift 正式开源!Swift 团队很高兴宣布 Swift 开始开源新篇章。自从苹果发布 Swfit 编程语言,就成为了历史上发展最快的编程语言之一。Swift 通过设计使得软件编写更加快速更加安全。 Swift 是由多种不同的项目组成...
  • swift5.0 原版文档,epub格式,很方便哦,希望帮助到需要的人
  • 该文章翻译自apple官方文档:The Swift Programming Language(Swift 4.1) A Swift Tour -- 一个Swift 旅行 Tradition suggests that the first program in a new language should print the words “Hello, world!...

    该文章翻译自apple官方文档:The Swift Programming Language(Swift 4.1)

    A Swift Tour  -- 一个Swift 旅行

    Tradition suggests that the first program in a new language should print the words “Hello, world!” on the screen. In Swift, this can be done in a single line:
    print("Hello, world!")

    译:传统认为,一种新语言的第一个程序应该打印“Hello world!”在屏幕上。 用Swift,它可以用简单的一行代码搞定。

    If you have written code in C or Objective-C, this syntax looks familiar to you—in Swift, this line of code is a complete program. You don’t need to import a separate library for functionality like input/output or string handling. Code written at global scope is used as the entry point for the program, so you don’t need a main()function. You also don’t need to write semicolons at the end of every statement.

    译:如果你用C或 OC写代码,这语法看起来很熟悉 —— 在 Swift里,这行代码就是一个完整的程序。你不需要为输入/输出或字符串处理之类的功能导入单独的库。在全局范围内编写的代码用作程序的入口点,所以你不需要一个主函数功能。你也不需要在每一个语句的末尾写分号。

    This tour gives you enough information to start writing code in Swift by showing you how to accomplish a variety of programming tasks. Don’t worry if you don’t understand something—everything introduced in this tour is explained in detail in the rest of this book.

    译:这个旅行给你足够的信息可以开始用Swift写代码,它展示给你怎样完成各项编程任务。不要担心如果你不理解一些部分 ——这个旅行里每一项在本书的其他部分都有详细的介绍。

    NOTE

    For the best experience, open this chapter as a playground in Xcode. Playgrounds allow you to edit the code listings and see the result immediately.

    Download Playground

    提示:

    为了一个更好的体验,在Xcode的里用一个playground打开本章内容,Playgrounds 允许你编辑代码列表并且立马看结果。

     

     

    Simple Values -- 简单的值

    Use let to make a constant and var to make a variable. The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once. This means you can use constants to name a value that you determine once but use in many places.

    1. var myVariable = 42
    2. myVariable = 50
    3. let myConstant = 42

    译:用 let 表示常量,用 var 表示变量,这个常量的值在编译时不需要知道,但是你必须马上赋给它一个确切的值。这意味着你可以用常量去为一个你定义的值命名,这个值可以在多处使用。

    A constant or variable must have the same type as the value you want to assign to it. However, you don’t always have to write the type explicitly. Providing a value when you create a constant or variable lets the compiler infer its type. In the example above, the compiler infers that myVariable is an integer because its initial value is an integer.
    If the initial value doesn’t provide enough information (or if there is no initial value), specify the type by writing it after the variable, separated by a colon.

    1. let implicitInteger = 70
    2. let implicitDouble = 70.0
    3. let explicitDouble: Double = 70

    EXPERIMENT

    Create a constant with an explicit type of Float and a value of 4.
     

    译:常量或变量必须与你赋给它的值有同样的类型.然而,然而你并不必须写出具体的类型.当你创建一个常量或变量时提供一个值可以让编译器判断它的类型,在上面的例子中,编译器判断 myVarible 是一个整数因为它的初始化值是一个整数.

    如果这个初始化的值没有提供足够的信息(或者如果没有初始化的值),可以通过在变量后面写下指定的类型,用冒号隔开

     尝试1
    创建一个有明确类型为Float的常量,值为4

     

    Values are never implicitly converted to another type. If you need to convert a value to a different type, explicitly make an instance of the desired type.

    1. let label = "The width is "
    2. let width = 94
    3. let widthLabel = label + String(width)

    EXPERIMENT

    Try removing the conversion to String from the last line. What error do you get?

    译:这个值是绝不能换成其他类型的,如果你需要将值转换为不同的类型,明确地做一个期望类型的实例
    实验
    试着从最后一行移除String转换,你得到什么错误?

     

    There’s an even simpler way to include values in strings: Write the value in parentheses, and write a backslash (\) before the parentheses. For example:

    1. let apples = 3
    2. let oranges = 5
    3. let appleSummary = "I have \(apples) apples."
    4. let fruitSummary = "I have \(apples + oranges) pieces of fruit."

    EXPERIMENT

    Use \() to include a floating-point calculation in a string and to include someone’s name in a greeting.
     

    译:这里有一个更简单的方式去在字符串里包含值:将这个值写进圆括号()里,并且在原括号前写一个反斜杠(\),例如:code
    实验
    用\()去在字符串里包含一个浮点值的计算并且在问候语里包含某个人的名字

     

    Use three double quotation marks (""") for strings that take up multiple lines. Indentation at the start of each quoted line is removed, as long as it matches the indentation of the closing quotation marks. For example:

    1. let quotation = """
      I said "I have \(apples) apples."
      And then I said "I have \(apples + oranges) pieces of fruit."
      """

    译:用三个双引号(" " ")来表示多行字符串。只要它匹配上结束引用标记的缩格,在每个引用行行头的缩格就是被删除的,例如:code

    Create arrays and dictionaries using brackets ([]), and access their elements by writing the index or key in brackets. A comma is allowed after the last element.

    1. var shoppingList = ["catfish", "water", "tulips", "blue paint"]
      shoppingList[1] = "bottle of water"
      
      var occupations = [
      "Malcolm": "Captain",
      "Kaylee": "Mechanic",
      ]
      occupations["Jayne"] = "Public Relations"

    To create an empty array or dictionary, use the initializer syntax.

    1. let emptyArray = [String]()
      let emptyDictionary = [String: Float]()

    If type information can be inferred, you can write an empty array as [] and an empty dictionary as [:]—for example, when you set a new value for a variable or pass an argument to a function.

    1. shoppingList = []
    2. occupations = [:]

    译:
    1.用([]) 方括号创建数组和字典,通过元素的索引或字典的key值访问到方括号中的元素。最后一个元素后面允许逗号.ex: code

    2. 用初始化语法创建一个空数组或字典

    3.如果类型信息可以被判断,你可以写一个空数组[],或空字典[:] -- 例如,当你设置一个值为一个变量或传一个参数给函数时.

     

     

    展开全文
  • 官方最新版本Swift 5.0 包括pdf和epub两个版本,pdf相比epub的好处就是可以使用Apple Pencil写写画画
  • 使用Swift5.0 遇到不少问题,有些是Xcode的bug,比如Xcode 11.2 使用 show in finder 显示文件位置,就会卡死,swift编译本来就慢,算了不抱怨了 1 通过setValuesForKeys保存字典数据,无法存储 参考文章:...
  • 该文章翻译自apple官方文档:The Swift Programming Language(Swift 5.0)   原文: This book describes Swift 5, the default version of Swift that’s included in Xcode 10.2. You can use Xcode 10.2 to ...
  • #必备 pod 'Alamofire' #网络请求 pod 'SwiftyJSON' #json解析 pod 'Kingfisher' #图片缓存 pod 'SwiftyUserDefaults' #UserDefaults pod 'IQKeyboardManagerSwift' ... pod 'SnapKit' #auto L...
  • 是百度网盘地址,1-22节课 1. 基本运算、流程控制、函数.mp4 2. 字符、字符串、枚举、集合、闭包】.mp4 3. 结构体、类、继承、属性、方法.mp4 4. init、deinit、extension.mp4 5. protocol、访问权限控制、反射.mp4 ...
  • 一、创建项目 这个很简单,创建好了看下面的就行了 二、添加权限 拍照和获取相册都需要先设置权限 ...实现一个简单的布局,同一个界面,一个按钮 Button,一张图片 ImageView ...1、要继承...
  • Demo主要介绍Swift的网络部分,代码已更新到swift4 –网络部分 请求均采用 Alamofire 请求封装方式分为: * 1.Moya(一个star很多的Alamofire的上层封装,为本demo推荐方式。我在使用过程中最终发现moya是极其...
  • 在上周发布 4.2 正式版本后,Swift 开发团队本周在官网更新了 “Swift 5.0 Release Process” ,主要介绍 Swift 5.0 的开发目标、发布流程和预估时间表。 和我们之前报道的一样,Swift 5.0 的主要目标是使语言实现 ...
  • Alamofire 可以通过CocoaPods 导入,也可以下载导入,这里是初学,CocoaPods 还不太熟悉,就直接下载导入使用了 1、Alamofire 下载 2、Alamofire 导入 3、Alamofire 使用 1、Alamofire 下载 ...
  • Swift5.0 基础语法

    2020-03-25 11:45:59
    swift5.0以后ABI已经趋于稳定语法不会有大变化 也是学习的最佳时机 var 定义变量 let 定义常量 常量只能赋值一次 使用之前必须赋值 例如: let view = UIView() view.frame = CGRect(x:0, y:0, width:10, ...
  • Swift 5.0 Hashable

    2019-06-10 18:36:58
    今天更新了Swift 5.0 原本遵守 Hashable 的地方出现了警告 具体使用如下 swift 5.0 写法 struct CacheEntry: Hashable { let text: String let width: CGFloat let insets: UIEdgeInsets let index: Int func ...
  • Swift 3.0 以来,语言已经比较成熟,用Swift语言来开发iOS App 的开发者越来越多,那么一份权威而全面的规范就很有必要了。苹果官方的文档一般都很少去看,笔者参考官方文档和各路大神的经验,写下了一份基于Swift...
1 2 3 4 5 ... 20
收藏数 4,366
精华内容 1,746
关键字:

5.0什么时候出 swift