Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Swift, can I use function type in tuple?

Tags:

swift

tuples

I want to use an array of tuples containing a function type. For example:

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

I then create the array:

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

But at compile time there are 2 errors on this statement:

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

So is it possible to use a function type on a tuple or do I miss something?

like image 385
Dominique Vial Avatar asked Feb 09 '23 22:02

Dominique Vial


2 Answers

You could do:

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

Unfortunately, trying to access an item in a tuple from the array results in Playgrounds breaking - 'Communication with the Playground service was unexpectedly interupted'. Trying the same thing in a project results in a segmentation fault. If you're getting the same problem I would recommend you use a struct instead:

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))
like image 65
ABakerSmith Avatar answered Feb 12 '23 12:02

ABakerSmith


I think there are two problems here: 1) requirement to use typealias for function types in tuple declarations, 2) compiler bug with dereferencing functions stored in tuples.

1. Adding a function

The compiler doesn't like finding function signatures in the tuple declarations. This feels like a bug to me, but I don't know the Swift specification well enough to say for sure.

typealias VoidToVoid = () -> ()

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

2. The compiler segfaults when trying to dereference the function.

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
like image 24
Brett Avatar answered Feb 12 '23 13:02

Brett