【问题标题】:Is this a valid case for use of a 'goto' in Java这是在 Java 中使用“goto”的有效案例吗
【发布时间】:2015-11-07 15:40:53
【问题描述】:

我非常清楚“goto”在结构化编程的大多数专业追随者的词典中是一个肮脏的词。所以我想问一下如何替换下面对“goto”的使用。

我正在编写一个桥牌竞价应用程序。我问用户“谁处理”。如果他这样做,没有问题。如果右边的玩家发牌(东),则必须询问用户该玩家的出价。如果对方发牌(伙伴),用户必须被问及对方的出价是什么,然后是什么东。如果用户左侧的玩家发牌(West),则必须依次询问用户这三个玩家的出价。

我有一个“出价什么”活动,该活动显示一个屏幕,并根据出价者传递“西方”、“您的合作伙伴”或“东方”。使用 startActivityForResult 调用该活动并返回已进行的出价。现在事情就是这样。我认为这是最有效的方法:

if (whodealt == "West") {continue}
else if (whodealt == "North") {goto northbid;}
else if (whodealt == "East") {goto eastbid;}
westbid:
 startActivityForResult() etc. passing "West";
 process result (e.g. store bid)
northbid:
  startActivityForResult() etc. passing "your partner";
  process result (e.g. store bid)
eastbid:
  startActivityForResult() etc. passing "East";
  process result (e.g. store bid)

显然,我已经简化了所有内容。但是下面的替代非goto结构是不是有点麻烦,比如

if (whodealt == "West") {
  startActivityForResult() etc. passing "West";
  process result (e.g. store bid)
  startActivityForResult() etc. passing "your partner";
  process result (e.g. store bid)
  startActivityForResult() etc. passing "East";
  process result (e.g. store bid) }

else if (whodealt == "North") {
  startActivityForResult() etc. passing "your partner";
  process result (e.g. store bid)
  startActivityForResult() etc. passing "East";
  process result (e.g. store bid) }

else if (whodealt == "East") {
  startActivityForResult() etc. passing "East";
  process result (e.g. store bid) }

人们对此有何看法?

【问题讨论】:

  • 首先,Java 中不会将字符串与 == 进行比较。您所做的是参照相等检查。
  • 您比较字符串的方式将始终返回 false,因为您将 objectstring 进行比较。
  • 你可以用一个开关做你想做的事。不过,对于 Android/Java 1.6,您必须先将字符串转换为枚举/整数。
  • 我认为你们没有抓住重点。
  • 你知道你的代码不会编译。 Goto 不是 Java 中的有效语句。

标签: java goto


【解决方案1】:

你所描述的本质上是一个带有失败的 switch 语句:

switch(whodealt) {
    case WEST:
        // startActivityForResult() etc. passing WEST;
        // process result
        // fall through

    case NORTH:
        // startActivityForResult() etc. passing NORTH;
        // process result
        // fall through

    case EAST:
        // startActivityForResult() etc. passing EAST;
        // process result
        // fall through

    case SOUTH: // (the player dealt themselves)
        break;
    default:
        throw new IllegalArgumentException("Unrecognised Dealer");
}

Java 从 Java 7 开始就支持 switch 语句中的字符串,但我建议不要为此使用字符串,并为经销商定义自己的枚举:在这种情况下,whodealt 只能存在有限的值域,并且比所有字符串的域都小很多。

【讨论】:

  • 谢谢你,安恩。所以并不是说如果“case WEST”为真,那么它就会跳到 switch 语句的末尾,因为我认为这就是发生的事情。它会在 WEST 然后 NORTH 然后 EAST 的情况下执行语句,而您不会告诉它失败?它是否正确?如果不是,你如何告诉它“失败”?
  • 没错,在switch 语句中,默认情况下会发生失败,您必须明确地将break 放入(就像我在SOUTH 案例中所做的那样)让它停止这样做。
  • 谢谢您,先生。您的答案现在已检查。
【解决方案2】:

Java 没有 goto 语句。 goto 是 Java 中的保留关键字,但该语言不使用它。请参阅此问题以获得更完整的答案。

Is there a goto statement in Java?

要回答您的问题“这是在 Java 中使用 'goto' 的有效案例吗”,答案必须是否定的,因为它在 Java 中是不可能的。

【讨论】:

    【解决方案3】:

    如果右边的玩家发牌(东),则必须询问用户该玩家的出价。如果对方发牌(搭档),则必须询问用户什么>对方出价,然后是什么东。如果用户左侧的玩家>发牌(西),则必须依次询问用户这三个玩家的出价。

    对于责任链来说似乎是一个很好的情况,特别是如果您希望实现更多逻辑代码。否则,我会建议使用类似 @amnn 的 switch case 语句。

    【讨论】:

    • “责任链”。听起来很有趣。你能指点我这方面的文档吗,因为虽然我当然可以猜到它的含义,但我不知道如何在 Java 中实现这样的东西。
    • 请参阅:link 我不知道您希望您的应用能走多远,但应该可以为离线和在线游戏实现不同的处理程序
    • 您必须考虑是否值得付出努力。 @amnn 上面提到了一个很好的解决方案
    • 谢谢。雅恩。按照我现在的目的和经验来说有点太高级了,但是已经记录了你的建议,当我有信心时很可能会回来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多