替换Swift中的goto语句

时间:2015-02-08 18:32:54

标签: swift goto control-flow

如何将控件转移到Swift代码中的特定行?

在Objective-C中,我会使用goto

执行以下操作
if(a==b)
{
    goto i123;
}
else
{
    goto i456;
}
NSLog(@"the not reachable point");
i123:
NSLog(@"line 123 is here");
int j = 5;
int x = 2+j;
i456:
NSLog(@"line 456 is here");

我可以找到Swift中唯一的控件转移语句是continuebreakfallthroughreturn

continuebreak仅适用于循环; returnfallthrough不会以这种方式转移控制权。

我可以使用什么?

修改: -

Julien __的回答并没有真正解决我的问题,但它可能是目前唯一可用的选项。所以我接受了Julien __

的回答

8 个答案:

答案 0 :(得分:5)

也许是一个转换声明?

switch (a==b){
default:
    NSLog(@"the not reachable point");
    fallthrough­
case true:
    NSLog(@"line 123 is here");
    int j = 5;
    int x = 2+j;
    fallthrough­
case false:
    NSLog(@"line 456 is here");
}

编辑:以下是你可以退步的方法。

let START = 0
let STOP  = -1
var label = START

while(label != STOP){
    switch (label){

    default:
        label = START­

    case START:
        NSLog(@"the not reachable point");
        if a==b {
            label = 123
        } else {
            label = 456
        }

    case 123:
        NSLog(@"line 123 is here");
        int j = 5;
        int x = 2+j;
        fallthrough­

    case 456:
        NSLog(@"line 456 is here");
        fallthrough

    case STOP:
        label = STOP
    }
}

将代码包装在一个巨大的(但组织良好的)switch语句中。您甚至可以创建一个名为goto的函数,以便修改标签var。

的值

答案 1 :(得分:4)

嗯...... Swift实际上支持标签,可以用作控制流的goto但不太灵活。以下代码来自Swift编程语言:

gameLoop: while square != finalSquare {
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }

    switch square + diceRoll {
    case finalSquare:
    // diceRoll will move us to the final square, so the game is over
        break gameLoop
    case let newSquare where newSquare > finalSquare:
    // diceRoll will move us beyond the final square, so roll again
    continue gameLoop
    default:
    // this is a valid move, so find out its effect
        square += diceRoll
        square += board[square]
    }
}
print("Game over!")

答案 2 :(得分:1)

这个怎么样?

var j : Int?
var x : Int?

if a == b {
    println("line 123 is here")
    j = 5
    x = 2 + j!
}
println("line 456 is here")

答案 3 :(得分:1)

似乎Swift并不希望任何人使用goto语句。可能要避免将来难以遵循的意大利面条代码。

一种可能的替代方法是使用功能。函数的名称与单纯的行号相比具有意义并且更容易理解。

答案 4 :(得分:1)

为了子孙后代:

  • 文章goto in Swift清楚地举例说明了如何实现goto样式功能,包括使用它们的原因的警告以及他们在语言中缺席的理由

  • 文章作者还将其作为GitHub上名为Goto.swift的Swift包提供。

答案 5 :(得分:0)

这是一个闭包({...}())方法:

let done = false
while !done {
    {
        for formantA in editedFormants {
            for formantB in editedFormants {
                if abs(formantA - formantB) < MIN_DISTANCE {
                    let newFormant = (formantA + formantB) / 2
                    editedFormants.removeAtIndex(editedFormants.indexOf(formantA)!)
                    editedFormants.removeAtIndex(editedFormants.indexOf(formantB)!)
                    editedFormants.append(newFormant)
                    editedFormants = editedFormants.sort()
                    return
                }
            }
        }
        done = true
    }()
}

答案 6 :(得分:0)

我确信您的代码可以重构以避免使用goto。或者,您可以在函数内使用函数,但仍可以访问外部参数。例如,

func foobar(a: Int, b: Int) {

    func i123() {
        let j = 5
        let x = 2+j
        print("i123 x=\(x) b=\(b)")
    }

    func i456() {
        print("i456")
    }

    if a == b {
        i123()
    } else {
        i456()
    }
}

答案 7 :(得分:0)

在可用的语言中,我不认为GoTo总是一件坏事。我永远不会用它在一个函数中向上,向下和向左跳跃。这不会导致混乱。但我喜欢使用GoTo给我一个共同的退出点。这是我的意思(伪代码)的例子:

func SomeFunction() -> Bool
{
    var iReturnValue = false;

    // Do some processing

    if(SomeCondition == true)
    {
        // return true;
        // No. Instead of having a return statement here.
        // I'd rather goto a common exit point.

        iReturnValue = true;
        goto ExitPoint;
    }

    // Do Some More processing

    if(SomeOtherCondition == SomeResult)
    {
        iReturnValue = false;
        goto ExitPoint;
    }

    //
    // More processing
    //

ExitPoint:
    // By having a common exit point I can do any
    // cleanup here and I've got a single return point
    // which I think makes my code easier to read.

    return iResultValue;
}

我知道我可以通过几个放置好的支架来实现同样的功能,但我发现使用良好的Goto可以让生活变得更加简单。