我正在进行ro sham bo游戏。 swift中的函数与我之前使用的函数不同。我一直收到错误:
在函数
中初始化之前使用的变量
我做错了什么?
import Foundation
import UIKit
class Result: UIViewController {
var rval: Int?
var chosen: Int?
func determineWinner() -> Int {
var returnval: Int
if (chosen == rval){
returnval = 2
}
else if (chosen == 1 && rval == 3){
returnval = 1
}
else if (chosen == 1 && rval == 2){
returnval = 0
}
else if (chosen == 2 && rval == 1){
returnval = 1
}
return (returnval)
}
@IBOutlet weak var wl: UILabel!
@IBAction func PlayAgain(sender: AnyObject) {
}
override func viewDidLoad() {
print(chosen)
}
}
答案 0 :(得分:1)
有问题的陈述是return (returnval)
,因为Swift编译器认为传递了if-then-else链而不会导致returnval
的分配。
例如,如果chosen
为3且rval
为2,则不会进行分配。
也许程序的其他部分使chosen
无法在rval
为2的同时成为3,但Swift不知道这一点,因此报告错误。要修复编译错误,请将初始值添加到returnval
。
如果您完全确定if-then-else链枚举所有有效的可能性,请将returnval
设置为-1
,并在返回之前设置为非负值的断言:
var returnval = -1
... // your conditionals go here
assert(returnval >= 0, "Logic of determineWinner is broken")
return returnval
答案 1 :(得分:1)
Swift程序流程中的每个可能路径都必须具有已定义的返回值。在您的情况下,如果全部跳过00
/ if
/ else if
部分,则会else
未分配。因此,不返回有效值。试试这个:
returnval
这也是使用switch
语句进行模式匹配的非常好的候选者。以下是我认为可以与Sean's suggestion.
import Foundation
import UIKit //space things out to be easier to read
class Result: UIViewController {
var rval: Int? //these should have better names
var chosen: Int?
func determineWinner() -> Int {
var returnval = -1 //needs a default value
if (chosen == rval){
returnval = 2
}
else if (chosen == 1 && rval == 3){
returnval = 1
}
else if (chosen == 1 && rval == 2){
returnval = 0
}
else if (chosen == 2 && rval == 1){
returnval = 1
}
return returnval //don't put return value in brackets
}
@IBOutlet weak var wl: UILabel!
@IBAction func PlayAgain(sender: AnyObject) {
}
override func viewDidLoad() {
print(chosen)
}
}
答案 2 :(得分:0)
尝试var returnval: Int = 0
(或其他随机数,以防你的if-else陈述详尽无遗)
答案 3 :(得分:0)
<强> EDITTED 强>
您收到初始值设定项错误,因为在设置之前您尚未使用returnval
初始化Int()
。
考虑使用计算属性来返回获胜者的值。我在下面的代码中做了假设,你使用的值2根据你的逻辑推断了一个平局情况。
在这里,我创建了一个枚举,以确保只能按照您期望结果的特定方式处理返回值。您仍然可以通过枚举案例中的哈希值访问Int
值。使用.rawValue
来执行此操作。
在这种情况下,尽量避免使用Int
值非常重要,因为它们可能是其他值。
在下面的代码中,我写了一组guard
语句失败,并在检查的值不允许确定获胜者状态时返回fatalError
消息。
改进代码
import Foundation
import UIKit
class Result: UIViewController {
var rval: Int?
var chosen: Int?
enum Winner: Int {
case one = 0
case two = 1
case tie = 2
}
var winner: Winner? {
guard (rval > 0 || rval < 4) else {
fatalError("rval out of bounds: cannot determine winner")
}
guard (chosen > 0 || chosen < 3) else {
fatalError("chosen out of bound: cannot determine winner")
}
guard (rval != nil && chosen != nil) else {
fatalError("rval or chosen are nil: cannot determine winner")
}
switch (chosen!, rval!) {
case (let chosen, let rval) where chosen == rval: return Winner.tie
case (1, 3): return Winner.two
case (1, 2): return Winner.one
case (2, 1): return Winner.two
default:
return nil
}
}
@IBOutlet weak var wl: UILabel!
@IBAction func PlayAgain(sender: AnyObject) {
}
override func viewDidLoad() {
print(chosen)
}
}
作为旁注,请务必为您喜欢的答案+1!
答案 4 :(得分:0)
正如其他人已经说过的那样,问题是没有满足您的条件,因此returnval
未初始化。
您可以使用switch语句+ guard + computed属性。喜欢这个
var winner: Int? {
guard let chosen = chosen, rval = rval else { return nil }
switch (chosen, rval) {
case (let chosen, let rval) where chosen == rval : return 2
case (1, 3): return 1
case (1, 2): return 0
case (2, 1): return 1
default: return nil
}
}
请注意我略微改变了你的逻辑。在我的代码中,如果选择并且rval都是nil,则返回值为nil。在您的代码2中返回。您应该更改它,可能在我的代码之上添加另一个
这样的东西guard
。像
guard chosen != rval else { return 2 }
如果您知道选择并且rval将始终填充
var winner: Int {
guard let chosen = chosen, rval = rval else { fatalError() }
switch (chosen, rval) {
case (let chosen, let rval) where chosen == rval : return 2
case (1, 3): return 1
case (1, 2): return 0
case (2, 1): return 1
default: fatalError()
}
}
答案 5 :(得分:0)
你可以让这更加活跃。
例如......为什么使用Int
来表示不同的动作?在这里,我使用枚举来表示动作以及胜利背后的逻辑...
enum RoShamBo {
case Rock
case Paper
case Scissors
func beats(opposingPlay: RoShamBo) -> Bool {
return self > opposingPlay
}
}
// I thought it made sense to make it Comparable.
// That way you can use the < or > operator to determine
// the winning move.
// I then used this in the function beats() above
extension RoShamBo: Comparable {}
func < (lhs: RoShamBo, rhs: RoShamBo) -> Bool {
// this is required for Comparable
// in this we return true if lhs loses to rhs
// Scissors beat Paper
return lhs == .Paper && rhs == .Scissors
// Paper beats Rock
|| lhs == .Rock && rhs == .Paper
// Rock beats Scissors
|| lhs == .Scissors && rhs == .Rock
}
然后您需要做的就是将它包装成某种Player
和Game
类型的东西......
struct Player {
let name: String
let move: RoShamBo
}
struct Game {
func winner(player1: Player, player2: Player) -> Player? {
if player1.move.beats(opposingPlay: player2.move) {
return player1
}
if player2.move.beats(opposingPlay: player1.move) {
return player2
}
// tie
return nil
}
}
let p1 = Player(name: "Oliver", move: .Rock)
let p2 = Player(name: "Geoff", move: .Scissors)
let game = Game()
let winner = game.winner(player1: p1, player2: p2)
print(winner)
//Output Optional(Player(name: "Oliver", move: RoShamBo.Rock))
在整个事情中没有使用过任何一个Int,你可以确切地看到获胜的动作是什么以及谁赢了......
Enums实际上比Swift中的功能强大得多。