我一直在尝试遵循Crystal规范。它展示了一个获取实例变量地址的示例。所以我有一个类似的函数,但是指向一个2d数组的实例
def map_ptr(x : Int32, y : Int32)
pointerof(@map[x][y])
end
其中@map
数组的定义类似于:
@map = Array(Array(Room)).new(SIZE) { Array(Room).new(SIZE, Room.new) }
(0...SIZE).each do |x|
(0...SIZE).each do |y|
room_type = ROOMS.sample
@map[x][y] = Room.new(room_type)
end
end
当我尝试在分配中使用map_ptr
函数时,如:current_room = map_ptr(0, 0)
, Crystal编译器给了我一个错误,只说:
Error: can't take address of @map[x][y]
为什么它说@map[x][y]
而不是Room
,这是它应该指向的实际类型?我哪里做错了?
@map[x][y]
是对Array#[]
的调用。你试图获取其返回值的指针地址。这个值从来没有被赋值到任何地方,所以它没有地址。
我假设您实际上想要获得@map
数组中元素x, y
的地址。首先,你应该意识到这是一个不安全的操作。Array
可以重新分配它的项,因此在添加项时,它内部的指针可能无效。如果你不打算添加项,也许最好使用Slice
,因为它有更多的稳定性保证。
Array
和Slice
都有一个#to_unsafe
方法,它返回指向第一项的指针。然后就是@map.to_unsafe[x].to_unsafe + y
,在第二次元里面得到一个指针。
Slice
:
class Room
end
SIZE = 5
map = Slice(Slice(Room)).new(SIZE) { Slice(Room).new(SIZE, Room.new) }
map.to_unsafe[3].to_unsafe + 2 # => Pointer(Room)@0x7f80a2b58e80