default 参数

Swift 的方法是支持默认参数的,也就是说在声明方法时,可以给某个参数指定一个默认使用的值。在调用该方法时要是传入了这个参数,则使用传入的值,如果缺少这个输入参数,那么直接使用设定的默认值进行调用。Swift对默认参数在参数列表中的位置没有限制。

    func sayHello1(str1: String = "Hello", str2: String, str3: String) {
        print(str1 + str2 + str3)
    }

    func sayHello2(str1: String, str2: String, str3: String = "World") {
        print(str1 + str2 + str3)
    }

    sayHello1(str2: "", str3: "World")
    sayHello2(str1: "Hello", str2: "")
   // 输出都是 Hello World

我们可能会注意到 NSLocalizedString 这个常用方法的签名现在是:

public func NSLocalizedString(_ key: String, 
                          tableName: String? = default, 
                             bundle: Bundle = default, 
                              value: String = default, 
                            comment: String) -> String

默认参数写的是 default ,这是含有默认参数的方法所生成的 Swift 的调用接口。当我们指定一个编译时就能确定的常量来作为默认参数的取值时,这个取值是隐藏在方法实现内部,而不应该暴露给其他部分。类似的还有Swift中的各类断言:

public func assert(_ condition: @autoclosure () -> Bool, 
                     _ message: @autoclosure () -> String = default, 
                          file: StaticString = #file,
                         line: UInt = #line)

... 和 ..<

Swift 中对 .....< 两个操作符的定义:

    /// Returns a closed range that contains both of its bounds.
    public func ...<Bound>(minimum: Bound, maximum: Bound) -> ClosedRange<Bound> where Bound : Comparable

    /// Returns a countable closed range that contains both of its bounds. 
    public func ...<Bound>(minimum: Bound, maximum: Bound) -> CountableClosedRange<Bound> where Bound : Comparable, Bound : _Strideable, Bound.Stride : SignedInteger


   /// Returns a half-open range that contains its lower bound but not its upper bound.
    public func ..<<Bound>(minimum: Bound, maximum: Bound) -> Range<Bound> where Bound : Comparable

   /// Returns a countable half-open range that contains its lower bound but not its upper bound.
    public func ..<<Bound>(minimum: Bound, maximum: Bound) -> CountableRange<Bound> where Bound : Comparable, Bound : _Strideable, Bound.Stride : SignedInteger

不难发现,其实这几个方法都是支持泛型的。这两个操作符接受一个实现 Comparable 协议的输入,并返回一个任意类型的并且符合Comparable 协议的 Range。在 Swift 中,除了数字以外另一个实现了 Comparable 的基本类型就是 String。也就是说我们可以通过 ... 或者 ..< 来连接两个字符串。一个常见的使用场景就是检查某个字符是否是合法的字符。比如想确认一个单词里的全部字符都是小写英文字母的话,可以这么做:

   let test = "helLo"
   let interval = "a"..."z"
   for c in test.characters {
        if !interval.contains(String(c)) {
            print("\(c) 不是小写字母");
        }
   }
// L 不是小写字母

在日常开发中,我们可能会需要确定某个字符是不是有效的 ASCII 字符,和上面的例子很相似, 我们可以使用 \0...~ 这样的 closeInterval 来进行 ( \0~ 分别是 ASCII 的第一个和最后一 个字符)。

第三个方法的使用示例:

    let lessThanFive = 0.0..<5.0
    print(lessThanFive.contains(3.14))  // Prints "true"    
    print(lessThanFive.contains(5.0))   // Prints "false"

第二个和第四个方法使用区间操作符 .....< 来创建一个任意类型的闭区间和开区间,这个区间符合 Strideable 协议,有一个关联的有符号整数 Stride 类型,如标准库中的任意一个整型。你可以对这个符合 Strideable 协议的区间使用 SequenceCollection 的方法。例如:

   let singleDigits = 0...9
   print(singleDigits.contains(9))  // Prints "true"

   // 你可以对 singleDigits 区间使用 sequence or collection 的方法.
   print(singleDigits.count)  // Prints "10"
   print(singleDigits.last)  // Prints "9"

   let upToFive = 0..<5
   print(upToFive.contains(3))         // Prints "true"
   print(upToFive.contains(5))         // Prints "false"

   // You can use sequence or collection methods on the `upToFive` countable range.
   print(upToFive.count)               // Prints "5"
   print(upToFive.last)                // Prints "4"

print 和 debugPrint

对某个特定的类型使用 CustomStringConvertible 协议,这个协议定义了将该类型实例输出时所用的字符串。相对于直接在原来的类型定义中进行更改,我们更应该倾向于使用一个 extension ,这样不会使原来的核心部分的代码变乱变脏,是一种很好的代码组织的形式:

extension Meeting:  CustomStringConvertible {
    var description: String {
        return "于 \(self.date) 在  \(self.place) 与  \(self.attendeeName) 进行会议 "
    }
}

CustomDebugStringConvertibleCustomStringConvertible 的作用很类似,但是仅发生在调试中使用 debugger 来进行打印的时候的输出。对于实现了 CustomDebugStringConvertible 协议的类型,我们可以在给 meeting 赋值后设置断点并在控制台使用类似 po meeting 的命令进行打印,控制台输出将为 CustomDebugStringConvertible 中定义的 debugDescription 返回的字符串。

extension Meeting: CustomDebugStringConvertible {
    var debugDescription: String {
        return "于\(self.date) 在 \(self.place)  与 \(self.attendName) 进行会议"
    }    
}
debugPrint(meeting)

results matching ""

    No results matching ""