【问题标题】:ViewModel function: Cannot assign to value: 'error' is a 'let' constantViewModel 函数:无法赋值:'error' 是 'let' 常量
【发布时间】:2018-07-13 06:40:12
【问题描述】:

我正在努力学习 swift ViewModel,并且我创建了一个函数来处理错误。

但是当我在 ViewController 文件中调用该函数时,它会显示:

Cannot assign to value: 'error' is a 'let' constant

有没有办法解决这个问题?我仍然是一名学生,正在寻找最好的建议。

非常感谢。

下面是我的代码,你们可以帮帮我吗。

SignUpError.swift :

class SingUpError {
    func errorMessage(name: String?, lastName: String?,email: String?, password: String?, error: String?){

        enum ErrorMessage: String {
            case noName = "Name cannot be empty"
            case noLastName = "Last name cannot be empty"
            case noEmail = "Email cannot be empty"
            case noPassword = "Password cannot be empty"
        }

        if name == "" {
            error = ErrorMessage.noName.rawValue
        }
    }
}

NewUserVC.swift :

class NewUserVC: UIViewController {

    // Var
    var vm = SingUpError()

    // Outlet Text Fields

    @IBOutlet weak var nameText: UITextField!
    @IBOutlet weak var lastNameText: UITextField!
    @IBOutlet weak var emailText: UITextField!
    @IBOutlet weak var passwordText: UITextField!

    // Outlet Labels

    @IBOutlet weak var nameErrLbl: UILabel!
    @IBOutlet weak var lastNameErrLbl: UILabel!
    @IBOutlet weak var emailErrLbl: UILabel!
    @IBOutlet weak var passwordErrLbl: UILabel!


    @IBAction func submiButton(_ sender: UIButton) {
        submitData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    func submitData() {
        guard
            let name = nameText.text,
            let lastName = lastNameText.text,
            let email = emailText.text,
            let password = passwordText.text
            else {return}

        vm.errorMessage(name: name, lastName: lastName, email: email, password: password, error: nameErrLbl.text)
    }
}

【问题讨论】:

  • 我真的不知道你在做什么,但你的代码试图改变作为参数传递的常量值,你不能这样做并且无论如何都没有效果。您是否尝试返回错误?
  • 我正在尝试返回错误,如果文本字段为空它将返回错误...
  • 以上函数不返回任何东西,也改一下
  • 尝试将输入error 设置为inout 怎么样?你应该可以修改它。

标签: ios swift


【解决方案1】:

我不完全确定你想用SingUpError 做什么(你的意思是SignUpError?)但这是我的尝试。基本上我将枚举移出 func 并让 func 返回一个字符串

class SingUpError  {
    enum ErrorMessage: String {
        case noName = "Name cannot be empty"
        case noLastName = "Last name cannot be empty"
        case noEmail = "Email cannot be empty"
        case noPassword = "Password cannot be empty"
    }

    func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String? {
        var message: String?

        if name == nil || name.isEmpty {
            message = ErrorMessage.noName.rawValue
        } //else if lastName...

        return message
    }
}

然后在submitData

if let error = vm.errorMessage(name: name, lastName: lastName, email: email, password: password) {
     nameErrLbl.text = error
}

【讨论】:

    【解决方案2】:

    你试图给常量赋值。

    你不能这样做,因为error 它是函数的参数。 如果您想从此函数中获取错误消息,您需要编写如下内容:

    return ErrorMessage.noName.rawValue
    

    改为

    error = ErrorMessage.noName.rawValue
    

    【讨论】:

      【解决方案3】:
      class SingUpError {
          func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String? {
      
              guard let _ = name else { return ErrorMessage.noName.rawValue }
      
              // <this seems incomplete, but..>
              enum ErrorMessage: String { 
                  case noName = "Name cannot be empty"
                  case noLastName = "Last name cannot be empty"
                  case noEmail = "Email cannot be empty"
                  case noPassword = "Password cannot be empty"
              }
      
              return nil
          }
      }
      

      【讨论】:

        【解决方案4】:

        你需要做这样的事情

        class SingUpError {
            func errorMessage(name: String?, lastName: String?,email: String?, password: String?, error: String?) -> String{
        
                var errorMessage : String = ""
        
                enum ErrorMessage: String {
                    case noName = "Name cannot be empty"
                    case noLastName = "Last name cannot be empty"
                    case noEmail = "Email cannot be empty"
                    case noPassword = "Password cannot be empty"
                }
        
                if name == "" {
                    errorMessage = ErrorMessage.noName.rawValue
                }
        
                return errorMessage
            }
        }  
        

        【讨论】:

          【解决方案5】:

          当你在 swift 上声明一个函数时,它的参数默认是 'let' 常量。而且我们不能为常量赋值。

          在您的情况下,您试图分配给“错误”变量,这是一个参数,因此是一个常量(let)。你不能这样做。

          您可能会返回错误消息

          class SingUpError {
              func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String{
          
                  enum ErrorMessage: String {
                      case noName = "Name cannot be empty"
                      case noLastName = "Last name cannot be empty"
                      case noEmail = "Email cannot be empty"
                      case noPassword = "Password cannot be empty"
                  }
          
                  if name == "" {
                      return ErrorMessage.noName.rawValue
                  }
          
                  return ""
              }
          }
          

          【讨论】:

          • 最后需要返回字符串,否则会给出错误“在预期返回字符串的函数中缺少返回”
          • 是的,没错。我们需要返回一个字符串。感谢您指出。
          【解决方案6】:

          首先,将此枚举从类 SignUpError 中取出

          enum ErrorMessage: String {
                  case noName = "Name cannot be empty"
                  case noLastName = "Last name cannot be empty"
                  case noEmail = "Email cannot be empty"
                  case noPassword = "Password cannot be empty"
              }
          

          其次,你可以像这样修改你的函数:

          func errorMessage(name: String?, lastName: String?,email: String?, password: String?) -> String? {
              if name == "" {
                  let error = ErrorMessage.noName.rawValue
                  return error
              }
              return nil
          }
          

          现在在你的 ViewController 中,你可以修改你的函数来得到这样的 errorMessage

          func submitData() {
              //YOUR EXISTING CODE HERE    
              if let errorMessage = vm.errorMessage(name: name, lastName: lastName, email: email, password: password) {
                  print("errorMessage:\(errorMessage)")
                  return
              }
          }
          

          或者您可以尝试使用相同的方法,但将错误作为 inout 参数传递。 similar question here

          【讨论】:

            【解决方案7】:

            正如其他答案所说,您不能分配给 'error' 参数,因为它是一个常量(如果您愿意,可以使用 let 变量)。现在您可以按照建议的方式修改函数以返回字符串,但最好采用更结构化的方法并实际抛出错误。

            这样的事情会做:

            enum sumbissionErrors: Error {
                case noName
                case noLastName
                case noEmail
                case noPassword
            
                var description: String {
                    switch self {
                    case .noName:
                        return "Name cannot be empty"
                    case .noLastName:
                        return "Last name cannot be empty"
                    case .noEmail:
                        return "Email cannot be empty"
                    case .noPassword:
                        return "Password cannot be empty"
                    }
                }
            }
            
            func submitData() throws {
                if nameText.text == nil || nameText.text!.isEmpty {
                    throw sumbissionErrors.noName
                }
            
                if lastNameText.text == nil || lastNameText.text!.isEmpty {
                    throw sumbissionErrors.noLastName
                }
            
                if emailText.text == nil || emailText.text!.isEmpty {
                    throw sumbissionErrors.noEmail
                }
            
                if passwordText.text == nil || passwordText.text!.isEmpty {
                    throw sumbissionErrors.noPassword
                }
            
                // Do whatever you want now that the data is valid.
            }
            
            @IBAction func submitButton(_ sender: UIButton) {
                do {
                    try submitData()
                }
                catch {
                    if let sumbmissionError = error as? sumbissionErrors {
                        switch sumbmissionError {
                        case .noName:
                            nameErrLbl.text = sumbmissionError.description
                        case .noLastName:
                            lastNameErrLbl.text = sumbmissionError.description
                        case .noEmail:
                            emailErrLbl.text = sumbmissionError.description
                        case .noPassword:
                            passwordErrLbl.text = sumbmissionError.description
                        }
                    } else {
                        // This will probably never happen but it indicates that some other more general error occured and needs to be handled here.
                    }
                }
            }
            

            这只是一个示例,就像您的原件一样,只会抛出它遇到的第一个错误。您可能希望重新构建所有内容以允许标记多个错误。 IE。有可能不止一个是空的。

            【讨论】:

              【解决方案8】:

              如果您想采用与以前相同的方法,那么您需要更改函数中的一些小事情。

              首先让函数参数为常量意味着你不能分配值,但如果你仍然需要为你的参数分配一些值,那么在函数中将有一种使用 inout 关键字的方式

              class SingUpError {
                  func errorMessage(name: String?, lastName: String?,email: String?, password: String?, error: inout String?){
              
                      enum ErrorMessage: String {
                          case noName = "Name cannot be empty"
                          case noLastName = "Last name cannot be empty"
                          case noEmail = "Email cannot be empty"
                          case noPassword = "Password cannot be empty"
                      }
              
                      if name == "" {
                          error = ErrorMessage.noName.rawValue
                      }
                  }
              }
              

              打电话

              vm.errorMessage(name: name, lastName: lastName, email: email, password: password, error: &nameErrLbl.text)
              

              这里也有一些参考链接

              When to use inout parameters?

              【讨论】:

                猜你喜欢
                • 2017-04-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-03-28
                • 1970-01-01
                • 2018-10-18
                • 1970-01-01
                相关资源
                最近更新 更多