user8271889
user8271889

Reputation:

Constant 'spacesLeft' inferred to have type '()', which may be unexpected Swift

I am building a Tic Tac Toe game with an AI using Xcode 8 and Swift. Here are the relevant variables I am using that are contributing to the error:

var allSpaces: Set<Int> = [1,2,3,4,5,6,7,8,9]
var playerOneMoves = Set<Int>()
var playerTwoMoves = Set<Int>()
var nextMove: Int? = nil

Inside a function defining how the AI will play there are these variables:

var count = 0

let spacesLeft = allSpaces.subtract(PlayerOneMoves.union(playerTwoMoves))

The latter results in the compiler warning:

Constant 'spacesLeft" inferred to have type '()', which may be unexpected

There is an if statement just below that says:

if allSpaces.subtract(playerOneMoves.union(playerTwoMoves)).count > 0 {
nextMove = spacesLeft[spacesLeft.startIndex.advancedBy(Int(arc4random_uniform(UInt32(spacesLeft.count))))]

}

The condition gives the following error:

Value of tuple type '()' has no member 'count'

The statement gives the following error:

Type '()' has no subscript members

I am struggling to find a solution.

Upvotes: 0

Views: 1069

Answers (4)

henrique
henrique

Reputation: 1112

The subtract(_:) function is a mutating function so it will mutate the Set your using to call the function.

From Apple Docs:

subtract(_:)

Removes the elements of the given set from this set.

The reason you're getting the errors is because this function returns Void which in Swift is a typealias for an empty tuple(from Swift's source code). Since Void has no subscripts nor count property/variable you get those errors.

Maybe you should take a look at the subtracting(_:) function, which returns a different Set.

From Apple Docs:

subtracting(_:)

Returns a new set containing the elements of this set that do not occur in the given set.

Upvotes: 0

David Pasztor
David Pasztor

Reputation: 54716

Set.subtract is a mutating function, so it modifies the Set in place and its return value is Void, which is just a type alias for an empty tuple, (), hence the warning.

You should call Set.substracting, which is the non-mutating version of subtract and returns Set<Set.Element>.

Upvotes: 0

chengsam
chengsam

Reputation: 7405

For the first warning, subtract returns Void, so use subtracting:

let spacesLeft = allSpaces.subtracting(playerOneMoves.union(playerTwoMoves))

For the second error, advancedBy is deprecated, you may change like this:

if spacesLeft.count > 0 {
    nextMove = spacesLeft[spacesLeft.index(spacesLeft.startIndex, offsetBy: Int(arc4random_uniform(UInt32(spacesLeft.count))))]
}

Upvotes: 1

mag_zbc
mag_zbc

Reputation: 6982

subtract modifies Set in place and doesn't return a value, you want to use subtracting

Upvotes: 2

Related Questions