【问题标题】:In Swift, can I use function type in tuple?在 Swift 中,我可以在元组中使用函数类型吗?
【发布时间】:2015-06-05 16:28:26
【问题描述】:

我想使用一个包含函数类型的元组数组。例如:

(Int,Bool,() -> () )

然后我创建数组:

var someList = [(Int,Bool,() -> () )]()

但是在编译时这个语句有2个错误:

  • Expected ',' separator
  • Expected expression in list of expressions

那么是否可以在元组上使用 函数类型 或者我错过了什么?

【问题讨论】:

    标签: swift tuples


    【解决方案1】:

    你可以这样做:

    typealias TupleType = (Int, Bool, () -> Void)
    var list = [TupleType]()
    

    不幸的是,试图从数组中访问元组中的项目 导致 Playgrounds 中断 - “与 Playground 服务的通信意外中断”。在项目中尝试相同的事情会导致分段错误。如果您遇到同样的问题,我建议您改用结构:

    struct MyStruct {
        let num: Int
        let bool: Bool
        let closure: () -> Void
    
        init(num: Int, bool: Bool, closure: () -> Void = {}) {
            self.num = num
            self.bool = bool
            self.closure = closure
        }
    }
    
    var list = [MyStruct]()
    list.append(MyStruct(num: 1, bool: true, closure: { println("Hello") }))
    list.append(MyStruct(num: 2, bool: false))
    

    【讨论】:

    • 向已经存在的元组添加第三个参数是改进现有代码的直接方法。不幸的是,它把我们带到了一些 twilight zone,所以使用 struct 是一个更好的解决方案。
    • 在您的示例中,您能否描述如何定义 MyStruct 类型的值,并将 closure 组件设置为 no 语句函数?
    • “无声明函数”是什么意思?
    • 一个什么都不做的函数,里面没有任何语句。
    • 这能回答你的问题吗? :) 作为替代方案,您可以将闭包设为可选。
    【解决方案2】:

    我认为这里有两个问题:1) 要求在元组声明中对函数类型使用typealias,2) 解引用存储在元组中的函数的编译器错误。

    1。添加函数

    编译器不喜欢在元组声明中查找函数签名。这对我来说感觉像是一个错误,但我对 Swift 规范的了解还不足以肯定地说。

    typealias VoidToVoid = () -> ()
    
    var c = [Int, Bool, VoidToVoid]()  // works
    var d = [Int, Bool, () -> ()]()    // syntax error
    

    2。尝试取消引用函数时编译器出现段错误。

    func performSideEffects() {
        println("Howdy")
    }
    
    c.append(1, true, performSideEffects)  // works
    c.count  // works
    c[0].2   // blows up. Although possible completions with correct type shows up
    
    0  swift                    0x00000001020272b8 llvm::sys::PrintStackTrace(__sFILE*) + 40
    1  swift                    0x0000000102027794 SignalHandler(int) + 452
    2  libsystem_platform.dylib 0x00007fff8131ff1a _sigtramp + 26
    3  libsystem_platform.dylib 0x00007fff5e2f0550 _sigtramp + 3707569744
    4  swift                    0x00000001019ea39d swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 9901
    5  swift                    0x0000000101954f4f swift::irgen::IRGenModule::emitGlobalTopLevel() + 159
    6  swift                    0x00000001019d4c59 performIRGeneration(swift::IRGenOptions&, swift::Module*, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, swift::SourceFile*, unsigned int) + 2121
    7  swift                    0x00000001019d5693 swift::performIRGeneration(swift::IRGenOptions&, swift::SourceFile&, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, unsigned int) + 51
    8  swift                    0x0000000101911087 frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 6647
    9  swift                    0x000000010190f4e6 main + 1814
    10 libdyld.dylib            0x00007fff829f15c9 start + 1
    11 libdyld.dylib            0x000000000000003b start + 2103503475
    

    【讨论】:

    • 我应该补充一点,如果您在 Swift 1.2 中需要此功能,ABakerSmith 回答的“使用结构”似乎是一个很好的方法。就一个要解决的 Swift 难题而言,我对这个问题很感兴趣。我不认为它会导致编译器错误。
    • 这很奇怪:我没有你在使用括号时提到的语法错误:var actionsList = [SKNode,SKAction]()
    • 天哪。你对那个虚假的语法问题是对的,没有错误,我错了。由于复制粘贴失明,我有一个不同的错字,我一直在复制。感谢收看。
    • 在我自己的代码中尝试此代码会导致编译错误:“表达式解析为未使用的左值”。添加()' at the end of the statement to obtain c[0].2()` 会导致您获得相同的结果:编译器段错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 2019-08-15
    • 2016-04-19
    • 2014-07-30
    • 2019-03-25
    • 1970-01-01
    • 2021-07-19
    相关资源
    最近更新 更多