Static function variables in Swift

FunctionStaticSwift

Function Problem Overview


I'm trying to figure out how to declare a static variable scoped only locally to a function in Swift.

In C, this might look something like this:

int foo() {
    static int timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}

In Objective-C, it's basically the same:

- (NSInteger)foo {
    static NSInteger timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}

But I can't seem to do anything like this in Swift. I've tried declaring the variable in the following ways:

static var timesCalledA = 0
var static timesCalledB = 0
var timesCalledC: static Int = 0
var timesCalledD: Int static = 0

But these all result in errors.

  • The first complains "Static properties may only be declared on a type".
  • The second complains "Expected declaration" (where static is) and "Expected pattern" (where timesCalledB is)
  • The third complains "Consecutive statements on a line must be separated by ';'" (in the space between the colon and static) and "Expected Type" (where static is)
  • The fourth complains "Consecutive statements on a line must be separated by ';'" (in the space between Int and static) and "Expected declaration" (under the equals sign)

Function Solutions


Solution 1 - Function

I don't think Swift supports static variable without having it attached to a class/struct. Try declaring a private struct with static variable.

func foo() -> Int {
    struct Holder {
        static var timesCalled = 0
    }
    Holder.timesCalled += 1
    return Holder.timesCalled
}

  7> foo()
$R0: Int = 1
  8> foo()
$R1: Int = 2
  9> foo()
$R2: Int = 3

Solution 2 - Function

Another solution

func makeIncrementerClosure() -> () -> Int {
    var timesCalled = 0
    func incrementer() -> Int {
        timesCalled += 1
	    return timesCalled
    }
    return incrementer
}

let foo = makeIncrementerClosure()
foo()  // returns 1
foo()  // returns 2

Solution 3 - Function

Swift 1.2 with Xcode 6.3 now supports static as expected. From the Xcode 6.3 beta release notes:

> “static” methods and properties are now allowed in classes (as an > alias for “class final”). You are now allowed to declare static stored > properties in classes, which have global storage and are lazily > initialized on first access (like global variables). Protocols now > declare type requirements as “static” requirements instead of > declaring them as “class” requirements. (17198298)

It appears that functions cannot contain static declarations (as asked in question). Instead, the declaration must be done at the class level.

Simple example showing a static property incremented inside a class (aka static) function, although a class function is not required:

class StaticThing
{
    static var timesCalled = 0

    class func doSomething()
    {
        timesCalled++
        
        println(timesCalled)
    }
}

StaticThing.doSomething()
StaticThing.doSomething()
StaticThing.doSomething()

Output:

1
2
3

Solution 4 - Function

Another solution

class Myclass {
    static var timesCalled = 0
    func foo() -> Int {
        Myclass.timesCalled += 1
        return Myclass.timesCalled
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnhgrifView Question on Stackoverflow
Solution 1 - FunctionBryan ChenView Answer on Stackoverflow
Solution 2 - FunctionmonadisView Answer on Stackoverflow
Solution 3 - FunctionDanielView Answer on Stackoverflow
Solution 4 - FunctionJ.qView Answer on Stackoverflow