【问题标题】:How to shorten this code to prevent duplication of code?如何缩短此代码以防止代码重复?
【发布时间】:2017-05-07 06:58:31
【问题描述】:

我有这个问题很久了。我正在尝试可视化 3 门问题,只是为了好玩和练习 Swift。所以我有:

3 个门,因此有 3 个不同的 IBActions & 所有门的 3 种功能。这些功能完全相同,只是每个代码中的门数不同。所以我想知道,我可以缩短这段代码吗?:

func openSecondChoice(whatDoorIsClickedOn: Int)
    {
        if whatDoorIsClickedOn == 1
        {
            if whatDoorIsClickedOn == doorWithNumber
            {
                UIButtonDoor1.setBackgroundImage( UIImage (named: "doorWithMoney"), for: UIControlState.normal)
            }
            else
            {
                UIButtonDoor1.setBackgroundImage( UIImage (named: "doorWithGoat"), for: UIControlState.normal)
            }
        }
        if whatDoorIsClickedOn == 2
        {
            if whatDoorIsClickedOn == doorWithNumber
            {
                UIButtonDoor2.setBackgroundImage( UIImage (named: "doorWithMoney"), for: UIControlState.normal)
            }
            else
            {
                UIButtonDoor2.setBackgroundImage( UIImage (named: "doorWithGoat"), for: UIControlState.normal)
            }
        }
        if whatDoorIsClickedOn == 3
        {
            if whatDoorIsClickedOn == doorWithNumber
            {
                UIButtonDoor3.setBackgroundImage( UIImage (named: "doorWithMoney"), for: UIControlState.normal)
            }
            else
            {
                UIButtonDoor3.setBackgroundImage( UIImage (named: "doorWithGoat"), for: UIControlState.normal)
            }
        }
    }

哎呀!这段代码太丑了!例如,如果用户按下 door1,我将调用函数“openSecondChoise(whatDoorIsClickedOn: 1)”。有没有办法缩短这个?谢谢!我这里不使用类,我应该使用它们吗?

【问题讨论】:

标签: swift code-duplication


【解决方案1】:

通常,当您开始使用123 等为变量名称添加后缀时,是时候改用数组了。这就是数组的用途。

使用包含您的UIButtonDoor1...UIButtonDoor3 的数组uiButtonDoors,您的函数可能如下所示:

func openSecondChoice(whatDoorIsClickedOn: Int) {
    let imageName = whatDoorIsClickedOn == doorWithNumber ? "doorWithMoney" : "doorWithGoat"
    uiButtonDoors[whatDoorIsClickedOn - 1].setBackgroundImage(UIImage(named: imageName), for: UIControlState.normal)
}

【讨论】:

  • whatDoorIsClickedOn == 3 会崩溃
  • Np。我认为您的解决方案 - 虽然比我的短 - 有点不方便,因为 OP 需要在方法本身之外更改她的代码结构......我想这真的只是一个品味问题。但是,我完全同意使用一系列按钮来获得更简洁的代码:)
  • 没关系,我已经习惯于更改我的整个代码了,呵呵 :) 你们的问题,我已经问过最后一个答案的人了,所以也许他已经回答了......但你正在使用这个:“让 imageName = whatDoorIsClickedOn == doorWithNumber ?”doorWithMoney”:“doorWithGoat”这到底是什么?它有什么作用?你为什么使用“==”而不是“=”?我以为你只是引用时使用“==”,因此它更像是一个“检查”功能,而不是实际更改某些内容。希望您理解这一点!谢谢!
【解决方案2】:
func openSecondChoice(whatDoorIsClickedOn: Int) {
  let imageName = whatDoorIsClickedOn == doorWithNumber ? "doorWithMoney" : "doorWithGoat"
  let image = UIImage(named: imageName)

  let button: UIButton

  switch whatDoorIsClickedOn {
  case 1:
    button = UIButtonDoor1
  case 2:
    button = UIButtonDoor2
  case 3:
    button = UIButtonDoor3
  default:
    fatalError("Cannot be. Switch must be exhaustive, that's why we need to use 'default' for a switch on Int.")
  }

  button.setBackgroundImage(image, for: .normal)
}

对于更短的版本,请查看@tuple_cat 的答案。

【讨论】:

  • 我使用了几个三元条件运算符而不是开关,但效果相同。 @tuple_cat 有更好的答案。
  • 或者,而不是整个开关:let button = [UIButtonDoor1, UIButtonDoor2, UIButtonDoor3][whatDoorIsClickedOn - 1]
  • 感谢您的宝贵时间。但是,您是说 tuple_cat 有更好的答案,所以我会考虑一下。但是给你一个问题,为什么在 if 语句上使用 switch 语句?我搜索了一下,得到了这个答案:stackoverflow.com/questions/1028437/…它仍然有效还是过时?
  • 当然它仍然有效。 switch 只是您工具箱中除if-else 之外的另一个工具。有很多优点,但您应该始终根据用例进行思考。然而,我个人发现自己使用switch 的频率更高,因为我开始使用 Swift 编码。这对语言来说感觉更自然,尤其是当你开始到处使用模式匹配时:)
【解决方案3】:

另一种方法,为了好玩。

import UIKit

class DoorGame {
    func setupButtons() {
        let buttons = [UIButton(), UIButton(), UIButton()]

        for (index, button) in buttons.enumerated() {
            button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
            button.setTitle("\(index)", for: .normal)
        }

        let winningIndex = Int(arc4random_uniform(UInt32(buttons.count)))

        buttons[winningIndex].tag = 1
    }

    @objc func buttonTapped(_ sender: UIButton) {
        let imageName = sender.tag == 1 ? "doorWithMoney" : "doorWithGoat"
        let image = UIImage(named: imageName)

        sender.setBackgroundImage(image, for: .normal)
    }
}

【讨论】:

  • 哇!这与上面的答案不同。不过谢谢你的时间。我不明白所有这些,例如:为什么在这里使用一个类而不是一个函数?为什么在“fun buttonTapped”之前使用“@objc”?最后:什么是“let imageName = sender.tag == 1?”doorWithMoney:“doorWithGoat””你怎么称呼它?是这样做的吗?它是一个条件,如果满足条件,“:”将正确答案与错误答案分开(条件是“?”之前的所有内容)?谢谢!
  • 这个答案的主题是使用tag属性在按钮上嵌入一些数据(tag == 1表示它是赢家),然后使用按钮上的修饰动作更改背景图像。它在课堂上,因为封装是良好程序设计的标志。 @objc 是一个高级主题,因此我建议您稍后阅读。通常这段代码会在视图控制器中,你不需要@objc,我只是想让它在 Swift 操场上编译,这就是我包含它的原因。 ?: 是条件运算符。这是if/else 声明的简写。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多