Class 如何通过实例变量的;实际的;上课?

Class 如何通过实例变量的;实际的;上课?,class,oop,crystal-lang,Class,Oop,Crystal Lang,我正在编写的程序将元素存储在一个名为grid的散列中,类型为Position=>LivingBeing | Thing。这个网格存储在映射上,我希望这个映射返回类Apple元素的位置,它是Thing的子类 但是,当使用typeof()获取类时,我得到的是livingbing | Thing而不是子类Apple 以下是Map类: class Map @@grid = {} of Position => LivingBeing | Thing def initialize() e

我正在编写的程序将元素存储在一个名为
grid
的散列中,类型为
Position=>LivingBeing | Thing
。这个
网格
存储在
映射
上,我希望这个
映射
返回类
Apple
元素的位置,它是
Thing
的子类

但是,当使用
typeof()
获取类时,我得到的是
livingbing | Thing
而不是子类
Apple

以下是
Map
类:

class Map
  @@grid = {} of Position => LivingBeing | Thing

  def initialize()
  end

  # Add an entity to the grid
  def add_entity(new_entity : LivingBeing | Thing)
    @@grid[new_entity.position] = new_entity
  end

  # Return the position of an object of class "something"
  def self.where_is?(something : Class)
    # First attempt was to get the key by the value
    # @@grid.key(something)

    @@grid.each do |position, thing|
      # Returns "thing #<Apple:0x55f1772085c0> at Position(@x=1, @y=2) is (LivingBeing | Thing)"
      puts "thing #{thing} at #{position} is #{typeof(thing)}"
      position if typeof(thing) == something
    end
  end
abstract class Thing
  getter position
  @name = "Unkown object"

  def initialize(@position : Position)
  end
end

class Apple < Thing
  @name = "Apple"
end
此处为
位置
结构:

struct Position
  getter x, y

  def initialize(@x : Int32, @y : Int32)
  end
end
以下是我试图通过的测试:

it "gives a random thing location based on its class" do
  world = Map.new()
  apple = Apple.new(Position.new(1, 2))
  puts "Apple type : #{typeof(apple)}" # Returns "Apple type : Apple"
  world.add_entity(apple)
  position = Map.where_is?(Apple)
  position.should eq Position.new(1, 2)
end
是否有一些类方法或函数可以提供给
Apple
类? 还是设计问题


谢谢你的回答

对于我的功能,我有一个解决方案:

  # Return the position of an object of class "something"
  def self.where_is?(something)
    @@grid.each do |position, thing|
      return position if thing.is_a?(typeof(something))
    end
  end
这是为了测试:

  it "gives a random thing location" do
    world = Map.new(4)
    apple = Apple.new(Position.new(1, 2))
    world.add_entity(apple)
    position = Map.where_is?(Apple.new(Position.new(0, 0)))
    position.should eq Position.new(1, 2)
  end
如果没有其他解决方案,我会像这样使用它。但是我更希望能够直接搜索类
Apple
,而不是创建
Apple

我希望能够做
position=Map.u在哪里?(苹果)
而不是
position=Map.where_?(Apple.new(position.new(0,0))
正如@RX14所说,您似乎想检查运行时的“类型”,即
.class
。下面是一个例子:

class Apple
  @name = "Apple"
end

def check(obj : Object)
  obj.class == Apple
end

a=Apple.new
p check(a)

您可以使用
forall
来解决此问题:

  # Return the position of an object of class "something"
  def self.where_is?(something : T.class) forall T
    @@grid.each do |position, thing|
      return position if thing.is_a?(T)
    end
  end
并使用
Map调用它。_在哪里?苹果
如你所愿


这是因为类型变量
T
(使用
forall T
引入)可以通过传入与
T.class
类型限制匹配的常量
Apple
推断为
Apple
T
是一个常数,你可以用它来编译你的代码,但是如果东西是a,它会返回位置吗?解决您的问题的方法?另外,
typeof(foo)
返回编译时类型,而
foo.is_a?
foo.class
在运行时运行。如果您希望编译代码,我更新了我的问题,添加了
位置。我试图用
位置if-typeof(thing)==something.is_a?(something)
替换
位置if-thing.is_a?(something)
,但我得到了以下错误:
需要标记“CONST”,而不是“something”