我将我的一个iOS应用程序移植到Swift3 / Xcode8。 我嵌入了一个C库,它需要一个类型为:
的函数参数char ***
在Swift2.3中,这被翻译成:
UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>
所以我可以在我的快速代码中声明指针:
let myPointer = UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>.alloc(1)
这很好用,直到我用Swift3更新到Xcode8,现在我收到编译错误:
Cannot convert value of type 'UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>>>' to expected argument type 'UnsafeMutablePointer<UnsafeMutablePointer<UnsafeMutablePointer<Int8>?>?>!'
我可以帮助我理解swift3中的变化吗?这个可选,可选,隐式解包可选(?)在这个上下文中意味着什么?我如何声明这种类型的指针?
答案 0 :(得分:0)
尝试
let myPointer = UnsafeMutablePointer<
UnsafeMutablePointer<
UnsafeMutablePointer<Int8>?>?>.allocate(capacity: 1)
或者,您也可以使用_Nonnull
注释将指针保持为非可选。假设C函数是void setPtr(char ***)
。您可以通过桥接标题将其声明写入Swift,如下所示:
void setPtr(char * _Nonnull * _Nonnull * _Nonnull);
然后在您的Swift代码中,您可以执行以下操作:
let myPointer = UnsafeMutablePointer<
UnsafeMutablePointer<
UnsafeMutablePointer<Int8>>>.allocate(capacity: 1)
setPtr(myPointer)
let myInt = myPointer.pointee.pointee.pointee
但是如果setPtr(char *** ptr)
在_Nonnull
不可用的情况下*ptr = NULL;
会发生什么呢?
_Nonnull
?然后Swift代码将在运行时崩溃。但是,在setPtr()
声明中使用您不需要let myPointer = UnsafeMutablePointer<
UnsafeMutablePointer<
UnsafeMutablePointer<Int8>?>?>.allocate(capacity: 1)
setPtr(myPointer)
let myInt = myPointer.pointee?.pointee?.pointee
注释的选项,您的Swift代码就会变为
_Nonnull
它在运行时不会崩溃。
因此,当您不使用from itertools import accumulate # Or copy accumulate equivalent Python code
from itertools import chain
# Calls could be inlined in listcomp, but easier to read here
starts = accumulate(chain((0,), v)) # Extra value from starts ignored when ends exhausted
ends = accumulate(v)
list1,list2,list3,list4 = [l[s:e] for s, e in zip(starts, ends)]
时,由Swift3强制执行的选项的方法更安全。