Swift中的静态函数变量

nhg*_*rif 92 static function swift

我试图弄清楚如何声明一个静态变量,只在本地作用于Swift中的函数.

在C中,这可能看起来像这样:

int foo() {
    static int timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}
Run Code Online (Sandbox Code Playgroud)

在Objective-C中,它基本相同:

- (NSInteger)foo {
    static NSInteger timesCalled = 0;
    ++timesCalled;
    return timesCalled;
}
Run Code Online (Sandbox Code Playgroud)

但我似乎无法在Swift中做这样的事情.我试过用以下方式声明变量:

static var timesCalledA = 0
var static timesCalledB = 0
var timesCalledC: static Int = 0
var timesCalledD: Int static = 0
Run Code Online (Sandbox Code Playgroud)

但这些都会导致错误.

  • 第一个抱怨"静态属性只能在类型上声明".
  • 第二个抱怨"预期声明"(在哪里static)和"预期模式"(在哪里timesCalledB)
  • 第三个抱怨"一行上的连续陈述必须用';'"(在冒号和之间的空格中static)和"预期类型"(在哪里static)
  • 第四抱怨"上的线连续语句必须由';’分隔"(在之间的空间Intstatic)和"预期声明"(等号下签)

Bry*_*hen 146

我不认为Swift支持静态变量而不将它附加到类/结构上.尝试使用静态变量声明私有结构.

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
Run Code Online (Sandbox Code Playgroud)

  • 敬畏,但我很难过,我们不得不求助于此. (16认同)
  • @NSCoder但是可以在多个函数中声明`struct Holder {...}`并且它们不会发生碰撞.如果没有这个`struct`样板,Swift可以支持`static let`. (6认同)

mon*_*dis 22

另一种方法

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

let foo = makeIncrementerClosure()
foo()  // returns 1
foo()  // returns 2
Run Code Online (Sandbox Code Playgroud)

  • 这是一种典型的javascript方式 (2认同)
  • 这也在Apple的文档中讲述:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html它似乎是与"函数编程"保持一致的最佳解决方案",但也有其他解决方案.这应该是公认的答案. (2认同)
  • 我很抱歉,但这是一个丑陋的黑客,为同一问题增加了更多的复杂性。你想说什么?在那种情况下,我更喜欢简单的类属性。@Brian Chen 的答案是您能得到的最接近的答案。我将他的答案用于触发器类型的解决方案。Daniel 可能是最符合 Apple 的 Swift 编程规则的人。 (2认同)

Dan*_*iel 18

带有Xcode 6.3的Swift 1.2现在支持静态.从Xcode 6.3 beta版发行说明:

现在允许在类中使用"静态"方法和属性(作为"类final"的别名).现在,您可以在类中声明静态存储属性,这些属性具有全局存储,并且在首次访问时(例如全局变量)会被懒惰地初始化.协议现在将类型要求声明为"静态"要求,而不是将它们声明为"类"要求.(17198298)

似乎函数不能包含静态声明(如所讨论的那样).相反,声明必须在类级别完成.

虽然不需要类函数,但显示静态属性在类(也称为静态)函数内递增的简单示例:

class StaticThing
{
    static var timesCalled = 0

    class func doSomething()
    {
        timesCalled++

        println(timesCalled)
    }
}

StaticThing.doSomething()
StaticThing.doSomething()
StaticThing.doSomething()
Run Code Online (Sandbox Code Playgroud)

输出:

1
2
3
Run Code Online (Sandbox Code Playgroud)

  • 丹尼尔,这实际上是微妙的(但重要的)不同于问题所要求的.我很欣赏答案.@rickster我理解你在说什么,并认为你的评论可以扩展到这个问题的一个很好的答案. (5认同)