推断常量 'spacesLeft' 具有类型 '()',这可能是 Swift 的意外
Posted
技术标签:
【中文标题】推断常量 \'spacesLeft\' 具有类型 \'()\',这可能是 Swift 的意外【英文标题】:Constant 'spacesLeft' inferred to have type '()', which may be unexpected Swift推断常量 'spacesLeft' 具有类型 '()',这可能是 Swift 的意外 【发布时间】:2017-07-20 15:19:32 【问题描述】:我正在使用 Xcode 8 和 Swift 构建一个带有 AI 的井字游戏。以下是我正在使用的导致错误的相关变量:
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
在定义 AI 将如何播放的函数内部有以下变量:
var count = 0
let spacesLeft = allSpaces.subtract(PlayerOneMoves.union(playerTwoMoves))
后者导致编译器警告:
推断常量 'spacesLeft' 具有类型 '()',这可能是意料之外的
下面有一个 if 语句说:
if allSpaces.subtract(playerOneMoves.union(playerTwoMoves)).count > 0
nextMove = spacesLeft[spacesLeft.startIndex.advancedBy(Int(arc4random_uniform(UInt32(spacesLeft.count))))]
条件给出以下错误:
元组类型'()'的值没有成员'count'
该语句给出以下错误:
类型'()'没有下标成员
我正在努力寻找解决方案。
【问题讨论】:
【参考方案1】:subtract
原地修改Set
不返回值,你要使用subtracting
【讨论】:
【参考方案2】:对于第一个警告,subtract
返回Void
,所以使用subtracting
:
let spacesLeft = allSpaces.subtracting(playerOneMoves.union(playerTwoMoves))
对于第二个错误,advancedBy
已弃用,您可以这样更改:
if spacesLeft.count > 0
nextMove = spacesLeft[spacesLeft.index(spacesLeft.startIndex, offsetBy: Int(arc4random_uniform(UInt32(spacesLeft.count))))]
【讨论】:
【参考方案3】:Set.subtract
是一个变异函数,所以它修改了Set
,它的返回值是Void
,这只是一个空元组()
的类型别名,因此是警告。
您应该调用Set.substracting
,这是subtract
的非变异版本并返回Set<Set.Element>
。
【讨论】:
【参考方案4】:subtract(_:)
函数是一个变异函数,所以它会变异你用来调用函数的 Set
。
来自Apple Docs:
subtract(_:)
从这个集合中移除给定集合的元素。
你得到错误的原因是因为这个函数返回Void
,它在Swift中是一个空元组的类型别名(from Swift's source code)。因为Void
没有下标也没有count
你得到的属性/变量那些错误。
也许你应该看看subtracting(_:)
函数,它返回一个不同的Set
。
来自Apple Docs:
subtracting(_:)
返回一个新集合,其中包含该集合中未出现在给定集合中的元素。
【讨论】:
以上是关于推断常量 'spacesLeft' 具有类型 '()',这可能是 Swift 的意外的主要内容,如果未能解决你的问题,请参考以下文章
KotlinKotlin 变量与常量 ( 变量声明 | 只读变量 | 类型推断 | 编译时常量 | Kotlin 字节码查看面板 | Kotlin 引用数据类型 )