Reputation: 3095
I created a small struct
to hold version numbers.
Now I searched a compact way to parse the numbers directly into the variables of the struct. I tried to implement it this way:
struct Version {
var major: Int = 0
var minor: Int = 0
var revision: Int = 0
init(string: String) {
let components = string.componentsSeparatedByString(".")
if 1...3 ~= components.count {
var targets = [&major, &minor, &revision]
for index in 0...2 {
var scanner = NSScanner(string: components[index])
if (!scanner.scanInteger(target[index])) {
major = 0
minor = 0
revision = 0
return
}
}
}
}
}
But I get this error message:
Type '[inout Int]' of variable is not materializable
I do not understand this error. Is there a way to implement it in this way, using a sort of pointers to the member variables?
In the end I did not use unsafe pointers. This was my final implementation:
init(string: String) {
let components = string.componentsSeparatedByString(".")
if 1...3 ~= components.count {
var values = [0, 0, 0]
for index in 0..<components.count {
var scanner = NSScanner(string: components[index])
if (!scanner.scanInteger(&values[index])) {
return
}
}
major = values[0]
minor = values[1]
revision = values[2]
}
}
Upvotes: 2
Views: 864
Reputation: 51911
in-out
is not UnsafePointer
nor UnsafeMutablePointer
, only if the function accepts Unsafe???Pointer<T>
family arguments, in-out expression will be passed as corresponding pointer types. see: the docs
try this:
var targets:[Int] = [0,0,0];
for index in 0...2 {
var scanner = NSScanner(string: components[index])
if (!scanner.scanInteger(&targets[index])) {
major = 0
minor = 0
revision = 0
return
}
}
major = targets[0]
minor = targets[1]
revision = targets[2]
OR
var targets:[UnsafeMutablePointer<Int>] = []
targets.append(&major)
targets.append(&minor)
targets.append(&revision)
for index in 0...2 {
var scanner = NSScanner(string: components[index])
if (!scanner.scanInteger(targets[index])) {
major = 0
minor = 0
revision = 0
return
}
}
Upvotes: 0
Reputation: 540105
The problem is how to get a pointer to the variables at all. It is possible
using withUnsafeMutablePointers()
:
init(string: String) {
let components = string.componentsSeparatedByString(".")
if 1...3 ~= components.count {
withUnsafeMutablePointers(&major, &minor, &revision) {
(p1, p2, p3) -> Void in
let targets = [p1, p2, p3]
for index in 0...2 {
var scanner = NSScanner(string: components[index])
if (!scanner.scanInteger(targets[index])) {
self.major = 0
self.minor = 0
self.revision = 0
break
}
}
}
}
}
but the code would probably better readable with three separate cases instead of a pointer array.
Upvotes: 3