Fattie
Fattie

Reputation: 12346

Better "nothing function" in Swift?

I have this structure,

typealias Tweak = (
    grab:(_ p: SomeClass)->CGFloat,
    change:(_ p: SomeClass, _ n: CGFloat)->(),
    from:CGFloat, upto:CGFloat
)

(So, the first line "gives you a value", the second "changes something", the last two are just limits.)

So, you might have an array of such things ...

var tweaks:[Tweak] = [
    ({_ in 0}, {_ in}, 0,0),

    (   {p in mainHeight},
        {p, n in
            mainHeight = n
            paintDisplayWhatever()},
        8.0, 28.0),

    (   {p in Some.global},
        {p, n in
            Some.global = n
            fireball.adjust(heat: n)},
        8.0, 28.0),

    etc

My question ...

notice the first one in the array, I simply wanted it to be the "nothing" version of a Tweak

So, I did this

nothingTweak: Tweak = ({_ in 0}, {_ in}, 0,0)

In Swift is there a better way to do the two "nothing" closures, or indeed, a more correct way to do the whole thing?

nothingTweak: Tweak = lessNilThanNil

you know?

Upvotes: 2

Views: 99

Answers (1)

Hamish
Hamish

Reputation: 80901

There's no built-in value that represents "a closure which returns a 0 CGFloat value", let alone a tuple of them along with two other zero values.

However if you create a type, such as a struct, to represent a Tweak (rather than using a typealias of a tuple), you can define static constant(s) to represent "default" values of a Tweak. For example:

class SomeClass {}

struct Tweak {

    // feel free to rename me to something more appropriate
    static let zero = Tweak(grab: {_ in 0 }, change: {_ in }, from: 0, upto: 0)

    var grab: (_ p: SomeClass) -> CGFloat
    var change: (_ p: SomeClass, _ n: CGFloat) -> Void
    var from: CGFloat
    var upto: CGFloat
}

Now wherever a Tweak is expected, you can just say .zero to refer to your "zero default" (this is exactly what types like CGPoint do):

var tweaks: [Tweak] = [

    .zero,

    Tweak(
        grab: { p in 25 },
        change: { p, n in
            print(p, n)
        },
        from: 8, upto: 28
    ),

    Tweak(
        grab: { p in 27 },
        change: { p, n in
            print(p, n * 4)
        },
        from: 8, upto: 28
    )
]

Creating a structure is much more preferable to creating a typealias of a tuple in this case. Tuples are only really designed to be transient types, not to be used for long-term storage. Structures are much more powerful and suited for long-term use.

Upvotes: 1

Related Questions