我现在正在学习Swift,在课程中我们有一个教训来制作一个简单的应用程序。现在我遇到了一些文本字段编程问题但是它无法正常工作。
这是我的代码:
class ViewController: UIViewController {
@IBOutlet weak var refeicaoField: UITextField?
@IBOutlet weak var felicidadeField: UITextField?
@IBAction func addRefeicao(sender: UIButton) {
if refeicaoField == nil || felicidadeField == nil {
return
}
let nomeRefeicao = refeicaoField!.text
let valorFelicidade = felicidadeField!.text
let valorFelicidadeInt = Int(valorFelicidade!)
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
}
}
问题从这里开始:
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
它所说的:可选的' Int?'没有打开;你的意思是使用'!'或'?'以及可选'字符串的价值?'没有打开;你的意思是使用'!'或者'?'
我有点困惑,因为在课程示例中他们这样做了:
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt!)
并且工作,但对我来说没有。如果我试着把'!'在这两个变量中,我有一个感叹号警告,提示不要使用novaRefeicao。
出了什么问题?
修改
使用此处的所有提示完成一些更改,现在我的代码就像:
class ViewController: UIViewController {
@IBOutlet weak var refeicaoField: UITextField!
@IBOutlet weak var felicidadeField: UITextField!
@IBAction func addRefeicao(sender: UIButton) {
if refeicaoField == nil || felicidadeField == nil {
return
}
let nomeRefeicao = refeicaoField!.text
let valorFelicidade = felicidadeField!.text
if nomeRefeicao == nil {
return
}
if let valorFelicidadeInt = Int(valorFelicidade!) {
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
} else {
return
}
}
}
现在我再次收到了解包的错误,但现在使用" nomeRefeicao"代替。试图把''!'在其中,但它表明让novaRefeicao是不可变的值。
答案 0 :(得分:3)
你应该明白,Swift语言在过去的一年中已经改变了 lot ,并且随着时间的推移感叹号已经发生了很大的变化。如果你的例子来自2015年中期,你就会看到过时的语法。
值为?
表示此项可能包含值...或者可能不包含值。
具有!
的值意味着您强行打开一个相当危险的对象,谨慎使用它,并且只有当您确定它不会导致崩溃时才会使用它。
如果你有一个可选值,你可以安全地打开它:
guard let unwrapped = wrapped else {
return
}
或
if let unwrapped = wrapped {
print(unwrapped)
}
更多信息,如果你有一个初始化的可选值,你真正得到的是:
enum Optional<A> {
case None
case Some(A)
}
这就是为什么你不能在没有展开它的情况下使用你的价值...它被“包裹”在可选枚举中,它具有值或不具有值。
添加了一点保护措施的代码:
class ViewController: UIViewController {
@IBOutlet weak var refeicaoField: UITextField?
@IBOutlet weak var felicidadeField: UITextField?
@IBAction func addRefeicao(sender: UIButton) {
guard let refeicaoField = refeicaoField!.text else {
return
}
guard let felicidadeField = felicidadeField!.text else {
return
}
let nomeRefeicao = refeicaoField ?? "error" // added protection
let valorFelicidade = felicidadeField ?? "error" // added protection
let valorFelicidadeInt = Int(valorFelicidade) ?? 0 // defaults to '0' in case of issue
}
}
答案 1 :(得分:2)
text
的{{1}}属性和UITextField
初始化程序的结果都返回一个可选值。
因此,如果方法需要非可选参数,则必须打开两者。
Int(string:String)
最紧凑的语法是
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao!, alegriaEmComer: valorFelicidadeInt!)
class ViewController: UIViewController {
@IBOutlet weak var refeicaoField: UITextField!
@IBOutlet weak var felicidadeField: UITextField!
@IBAction func addRefeicao(sender: UIButton) {
if let nomeRefeicao = refeicaoField.text, valorFelicidade = felicidadeField.text, valorFelicidadeInt = Int(valorFelicidade) {
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
// do something with novaRefeicao
}
}
}
初始化程序仅在
Meal
不是refeicaoField.text
nil
不是felicidadeField.text
,可以转换为nil
无需检查Int
的{{1}}个实例
如果出现运行时错误,则其中一个字段未在IB中连接。
消息UITextField
是一个警告,因为从未使用分配给nil
的已创建Initialization of immutable value ...
实例。这就是为什么我添加评论行做某事......
答案 2 :(得分:1)
该行:
any?
将let valorFelicidadeInt = Int(valorFelicidade!)
值转换为String
。如果字符串无法转换为整数,您的代码应该怎么做?你需要明确解决这个问题。
在Swift中,转换的类型为Int
- 转换有效或无效。因此,您有两个案例要涵盖。以下是一种可能的方法:
Optional
如果if let valorFelicidadeInt = Int(valorFelicidade!) {
let novaRefeicao = Meal(nomeAlimento: nomeRefeicao, alegriaEmComer: valorFelicidadeInt)
// continue using `Meal`
}
else {
// User error; text not an int
}
返回非零可选项,if let
将成功;然后,您将构建Int(...)
。
通过处理这两个选项进行解包的方法同样适用于代码的其他部分。