尝试理解地图,然后写一个来测试它,
func map<A, B>(x: A?, f: A -> B) -> B? {
if let x1 = x {
return f(x1)
}
return nil
}
let test1 = [1, 2, 3, 4]
println(test1)
let test2 = map(test1, { $0 + 1 })
println(test2)
let test3: [Int?] = [5, nil, 7, 8]
println(test3)//[{Some "aaa"}, {Some "bbb"}, nil, {Some "ccc"}]
let test4 = map(test3, { $0 + 1 })
println(test4) //"Optional(0x00007fb7ea61e190)"
但为什么test4无法输出值,只显示一个指针?
答案 0 :(得分:5)
指针说明
这里发生的是你正在将数组隐式转换为指针,这是出于C兼容目的。
通常,您无法将1
添加到数组中。我的意思是,这样做意味着什么?但是,Swift确实将数组隐式转换为指针,因此您可以将数组传递给C函数:
import Darwin
// prints out “hello” using a standard C function that takes a char*
puts([104,101,108,108,111,0])
你可以为指针添加整数(做好ol'指针算术):
// x will be an UnsafePointer<Int>
let x = [1,2,3] + 1
现在,为了阻止你意外地执行此操作,只有假设才能处理文字:
let a = [104,101,108,108,111,0]
// error: binary operator '+' cannot be applied to operands of type '[Int]' and 'Int'
let x = a + 1
但是当使用泛型函数时,这种转换仍然会发生(可能是无意的)。
地图问题
从您的定义看,您正在尝试为选项编写map
版本 - 也就是说,需要一个可选项,并在内容中映射内容。
但是,不是映射选项,而是将它用于序列。事实上,在您的代码段中,在let test2 = map(test1, { $0 + 1 })
行上,您根本没有调用map
- 您正在调用采用序列的标准库版本(并返回一个数组)。尝试在那里放一个assert(false)
- 你会发现第一次没有调用它。
选项的映射和数组的映射在概念上非常相似。这是因为选项和数组都是“仿函数” - 可以“映射”的东西的名称。将它们视为容器 - 包含其他类型的类型。在可选项的情况下,它们包含或不包含值。在数组的情况下,它们包含任意数量的值。但是在这两种情况下,有一个函数可以应用于“内容”,同时将它们留在“容器”中。
请考虑以下代码。它有两个映射,用于序列和选项,并依次应用它们。最后一个例子似乎是你在问题的最后一个案例中寻找的 - 在一个选项数组的每个成员上映射加一。这实际上是两张地图,一张在另一张中。
func mymap<A, B>(x: A?, transform: A -> B) -> B? {
println("map for optionals called!")
if let x1 = x {
return transform(x1)
}
return nil
}
func mymap<S: SequenceType, T>(source: S, transform: S.Generator.Element -> T) -> [T] {
println("map for sequences called!")
var result: [T] = []
for x in source {
result.append(transform(x))
}
return result
}
let test1 = [1, 2, 3, 4]
// prints "map for sequences called!"
let test2 = mymap(test1, { $0 + 1 })
println(test2) // prints
let test3: Int? = 5
// prints "map for optionals called!"
let test4 = mymap(test3, { $0 + 1 })
println(test4) // Optional(6)
let test5: [Int?] = [1, nil, 3, 4]
// prints "sequences called" followed by 4 "optionals called"
let test6 = mymap(test5) { mymap($0) { i in i + 1 } }
println(test6) // [Optional(2), nil, Optional(4), Optional(5)]