Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tuple vs Struct in Swift

I understand that Swift's tuples serve, for example, as a simple way for a function to return multiple values. However, beyond this "simplicity aspect", I don't see very well any necessity of using tuples instead of structs.

Therefore, my question: in terms of design, is there any scenario where tuples are clearly a better choice than structs?

like image 417
George Avatar asked Feb 02 '16 12:02

George


People also ask

Is tuple a struct Swift?

According to apple, a tuple type is a comma-separated list of zero or more types, enclosed in parentheses. It's a miniature version of a struct. The type of a tuple is determined by the values it has. So ("tuple", 1, true) will be of type (String, Int, Bool) .

When would you use a tuple instead of a struct?

You use a struct for things that meaningfully belong together to form a whole. You use a tuple for things that are together coincidentally. You can use a tuple spontaneously in your code.

Is tuple a struct?

They are structures (value types) rather than classes (reference types). They are mutable rather than read-only. That is, the value of tuple components can change. Their data members, such as Item1 , Item2 , etc., are fields rather than properties.

What is a tuple in Swift?

A tuple type is a comma-separated list of types, enclosed in parentheses. You can use a tuple type as the return type of a function to enable the function to return a single tuple containing multiple values.


1 Answers

This question of a slightly "discussion" nature, but I'll add two points in favour of sometimes preferring tuples over structures.


Native Equatable conformance for limited sized tuples

In Swift 2.2, tuples of up to size 6 will be natively equatable, given that it's members are equatable

  • Proposal SE-0015: Tuple comparison operators

This means tuples will sometimes be the natural choice over using smaller constructs in a limited scope.

E.g. consider the following example, using (1): a structure

struct Foo {
    var a : Int = 1
    var b : Double = 2.0
    var c : String = "3"
}

var a = Foo()
var b = Foo()

// a == b // error, Foo not Equatable

/* we can naturally fix this by conforming Foo to Equatable,
   but this needs a custom fix and is not as versatile as just 
   using a tuple instead. For some situations, the latter will
   suffice, and is to prefer.                                  */
func == (lhs: Foo, rhs: Foo) -> Bool {
    return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c
}

and (2): a tuple

/* This will be native in Swift 2.2 */
@warn_unused_result
public func == <A: Equatable, B: Equatable, C: Equatable>(lhs: (A,B,C), rhs: (A,B,C)) -> Bool {
    return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2
}
/* end of native part ...           */

var aa = (1, 2.0, "3")
var bb = (1, 2.0, "3")

aa == bb // true
aa.0 = 2
aa == bb // false

Generic access to different type tuples: more versatile than for different type structures

From the above (compare the == functions) it's also apparent that tuples are easily to work with in the context of generics, as we can access their anonymous member properties using the .0, .1 ... suffixes; whereas for a struct, the easiest way to mimic this behaviour quickly becomes quite complex, needing tools such as runtime introspection and so on, see e.g. this.

like image 140
dfrib Avatar answered Sep 28 '22 06:09

dfrib