Swift 5.4 - SE-0284 Allow Multip

2022-01-04  本文已影响0人  ienos

在 Swift 5.4 允许多个可变参数在方法、下标、初始化方法


Variadic Parameter Definify

可变参数(variadic parameter)可以接受零或多个值,通过在变量类型后面加入 (...) 的方式来定义

Before & After

在 Swift 5.4 之前,只允许一个可变参数在参数列表中,每一个可变参数均需要添加标签。修改后允许多个可变参数,并且只需要限制在可变参数后面的参数有标签

Motivation

在 Swift 5.4 之前

    func assertArgs(
        _ args: String...,
        parseTo driverKind: DriverKind,
        leaving remainingArgs: ArraySlice<String>,
        file: StaticString = #file, line: UInt = #line) { }

      /// 这里 leaving 用的是数组 [], 且声明为 ArraySlice<String>,受只有一个可变参数的限制
//    try assertArgs("swift", "-foo", "-bar", parseTo: .interactive, leaving: ["-foo", "-bar"])

如果参数列表允许有多个可变参数,代码将会更加简洁

    func assertArgs(
        _ args: String...,
        parseTo driverKind: DriverKind,
        leaving remainingArgs: String...,
        file: StaticString = #file, line: UInt = #line) { }
//    try assertArgs("swift", "-foo", "-bar", parseTo: .interactive, leaving: "-foo", "-bar")

Detailed Design

Section 0 : 在 twoVarargs 中,a 和 b 都是 Int 型,需要知道 a 可变参数列表,在什么时候结束

    func twoVarargs(_ a: Int..., b: Int...) {}
    /// 可变参数默认值是 [], 所以可以不传
    func test_twoVarargs() {
        /// b 参数省略,默认为 []
        twoVarargs(1, 2, 3)
        /// a 参数省略,默认为 []
        twoVarargs(b: 4, 5, 6)
        /// a 和 b 参数均省略,默认为 []
        twoVarargs()
    }

Section 1 : 两个可变参数被一个其他参数分割,且后面一个可变参数省略标签

    func splitVarargs(a: Int..., b: Int, _ c: Int...) {}
    func test_splitVarargs() {
        /// a = [1, 2, 3], b = 4, c = [5, 6]
        splitVarargs(a: 1, 2, 3, b: 4, 5, 6)
        /// a = [], b = 4, c = []
        splitVarargs(b: 4)
    }

Section 2 : 两个可变参数被一个其他参数分割,且两个可变参数均省略标签

    func varargsSplitByDefaultParam(_ a: Int..., b: Int = 42, _ c: Int...) {}
    func test_varargsSplitByDefaultParam() {
        /// a = [1, 2, 3], b = 4, c = [5, 6, 7]
        varargsSplitByDefaultParam(1, 2, 3, b: 4, 5 ,6, 7)
        /// a = [], b = 4, c = [6, 7]
        varargsSplitByDefaultParam(b: 4, 5, 6, 7)
        /// a = [1, 2, 3], b = 42, c = []
        varargsSplitByDefaultParam(1, 2, 3)
    }

目前像这种不同类型的也还不能自动识别,需要手动添加标签进行隔离

    /// 编译报错
//    func varargs(a: Int..., _ b: String) {}

下标 : 现在下标方法默认需要指定标签

    subscript(a: Int..., b b: String) -> Int { 0 }
    func test_subscript() {
        let _ = self[1, b: "12"]
    }

    /// 以下均编译报错
//    subscript(a: Int..., b: String) -> Int { 0 }
//    subscript(a: Int..., c: String = "Hello, World!") -> Bool { false }
上一篇下一篇

猜你喜欢

热点阅读