我承认感觉有点愚蠢,但经过几个小时的尝试后我不得不问:
class AGE {
static func getAge() -> Int {
var age: Int
for items in dataArray {
if items.name == "Steven" {
age = items.age
}
else {
age = 0
}
}
// variable "age" used before being initialized - WHY?
return age
}
}
我甚至尝试在开头设置var age: Int = 0
,然后设置函数return 0
。我希望有人可以原谅我这个基本问题。任何帮助表示赞赏。
为了更清楚地说明dataArray的样子:
struct Person {
let name: String
let lastName: String
let age: Int
}
let person1: Person = Person(name: "Steven", lastName: "miller", age: 23)
let person2: Person = Person(name: "jana", lastName: "drexler", age: 31)
let person3: Person = Person(name: "hanna", lastName: "montana", age: 56)
var dataArray = [Person]()
dataArray.append(person1)
dataArray.append(person2)
dataArray.append(person3)
更新
尝试汇总所有答案的精髓,解决方案必须如下所示: AGE {
static func getAge() ->Int {
var age: Int = 0
for items in dataArray {
while items.firstName == "Steven" {
age = items.age
return age
break // This break will never be executed because of return.
}
break // setting the break here, the loop will break after first round
}
return age
}
}
此代码有效,(第二次中断)但仅适用于第一个循环。剩下的问题是,如何在循环达到目标后设置返回和中断。返回或中断将阻止另一步。
答案 0 :(得分:3)
导致age
返回前初始化的可能程序流路径并非详尽无遗。如果dataArray
为空,则永远不会输入for ... in
循环的正文,并且永远不会初始化age
。在您的特定示例中解决此问题的最简单方法是在声明时将age
初始化为0
。
关于“意外”0
返回,即使dataArray
包含name
属性值为"Steven"
的元素:for ... in
中的每个传递不的循环包含name
属性值为"Steven"
的元素,您将将age
的值重置为0
< / em>的。这意味着,只有当"Steven"
值元素是dataArray
的最后一个元素时,非0
age
值才会存在。我没有看到任何理由在初始化之后再次将age
设置为0
,因此您可以通过以下方式解决此问题:在匹配的情况下,从break
循环执行提前退出(for
)。或者,根据您要实现的目标,只需在首次匹配时从方法中return
items.last_updated
(只需注意早期return
语句可能会影响性能)。
答案 1 :(得分:2)
我不是Swift开发者,但我怀疑这些逻辑是否正确。假设您在其他答案中建议将年龄初始化为0,那么在找到匹配&#34; Steven&#34;进入数组,你应该退出。否则,下一次迭代可以将年龄再次设置为零。
请记住,默认情况下for
语句会遍历所有元素。如果要迭代直到满足条件,那么while
可能更合适。
我已阅读tutorial并使用swift sand box在线测试此代码。在this link上分享我的代码。
class AGE {
static func getAge() -> Int {
var age = 0
var found = false
var current = 0
var allElementsChecked = (dataArray.count == 0) //is false unless array is empty
while !found && !allElementsChecked {
found = (dataArray[current].name == "Steven")
allElementsChecked = (current == dataArray.count-1)
current += 1
}
if found
{
age = dataArray[current-1].age //minus 1 to undo last increment within loop
}
return age
}
}
从循环中出来可能是因为&#34; Steven&#34;被发现或所有元素都被检查但未找到。
答案 2 :(得分:2)
如其他答案中所述,问题是如果数组为空,则永远不会设置变量。
除此之外,如果Steven
是数组中的最后一项,则代码效率低下并仅返回预期结果。否则,变量age
将被0覆盖。
然而在Swift中,过滤数组中的项比使用重复循环更方便,例如first(where:
class AGE {
static func getAge() -> Int {
return dataArray.first(where: { $0.name == "Steven" })?.age ?? 0
}
}
或者如果nil
不在数组中,则最好返回Steven
class AGE {
static func getAge() -> Int? {
return dataArray.first(where: { $0.Name == "Steven" })?.age
}
}
PS:代码中的last_updated
根本与结构Person
无关。
答案 3 :(得分:1)
您需要在开始时初始化它:
var age: Int = 0
如果由于某种原因你的for循环没有执行,那么当你只宣称它为var age: Int
并且没有将其设置为启用时,你就无法设置你的年龄变量。
关于:
我甚至尝试在开头设置
var age: Int = 0
,但接着是。{ 函数返回0
这意味着您已将您的age variable
和0
以及从未执行过的for循环进行了入侵,并且返回将为0
。
答案 4 :(得分:0)
我测试了Vadian的答案,根据您的要求,这似乎是正确的答案。
不过,这里还有其他建议:
首先,根据您的 Person 结构创建另一个数组实例:
var filteredPerson = [Person]()
如果您要根据名字 在dataArray中搜索年龄:
func getAge(of name: String){
filteredPerson = dataArray.filter { $0.name == name }
print (filteredPerson[0].age) }
获取“史蒂文”的 age 值:
getAge(of: "Steven")
您将得到结果:23。
请注意,您还可以通过return来获取 Int 值:
func getAge(of name: String) -> Int {
filteredPerson = dataArray.filter { $0.name == name }
return filteredPerson[0].age }
另一方面,如果列表中有很多名称的人,并且您想获得年龄特定 Person 的值,只需添加 lastName 参数:
func getAge(name: String, lastName: String){
filteredPerson = dataArray.filter { $0.firstName == name && $0.lastName == lastName }
print (filteredPerson[0].age) }
然后通过调用获取 age 值:
getAge(name: "Steven", lastName: "Miller")
希望这可以以某种方式帮助某人:)