You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Crystal中创建二维Array?Ruby写法的等效实现

Hey there! Let's walk through fixing your 2D array issues in Crystal, starting with matching your original Ruby code and then addressing those errors you ran into.

First: Equivalent of Your Ruby 2D Array in Crystal

Your Ruby code creates a 2D array of empty arrays:

rooms = Array.new(SIZE) { Array.new(SIZE) }
rooms[0][0] = :element

In Crystal, the syntax is almost identical—you just need to be explicit about types (since it's statically typed):

# Define your SIZE constant first (e.g., SIZE = 5)
rooms = Array.new(SIZE) { Array(Symbol).new(SIZE) }
rooms[0][0] = :element

If you don't need pre-allocated slots in the inner arrays, you could also use [] of Symbol instead of Array(Symbol).new(SIZE), but note that accessing rooms[0][0] would throw an index error unless you first add elements to the inner array.


Fixing the "instance variable not initialized" Error

Your first Map class failed because Crystal requires instance variables to be directly initialized in initialize methods—you can't use an instance variable before setting it first. Plus, Crystal distinguishes between single-quoted chars ('T') and double-quoted strings ("Test"), so you'll want to fix that too.

Here's the corrected version:

class Map
  @rooms : Array(Array(String))
  SIZE = 5 # Replace with your actual size

  def initialize
    # First initialize the 2D array: create SIZE inner arrays, each with SIZE empty strings
    @rooms = Array.new(SIZE) { Array(String).new(SIZE, "") }
    # Now you can safely assign to the index
    @rooms[0][0] = "Test"
  end
end

If you want inner arrays to start with nil instead of empty strings, change the type to Array(Array(String?)) (the ? marks it as nilable):

class Map
  @rooms : Array(Array(String?))
  SIZE = 5

  def initialize
    @rooms = Array.new(SIZE) { Array(String?).new(SIZE) }
    @rooms[0][0] = "Test"
  end
end

Fixing the IndexError in Your Nested Loop

Your second attempt hit an index error because Array(Array(Room)).new(SIZE) creates an array of SIZE nil values—but Array(Room) is a non-nilable type, so this line is actually invalid in Crystal (you'd get a type error before even running it!). Even if you bypassed that, assigning to @map[i] might not work as expected if the array wasn't properly initialized.

Instead, initialize the 2D array with a block to ensure every inner array exists, or build rows dynamically:

Option 1: Pre-allocate with blocks (cleanest)

SIZE = 5
ROOMS = ["bedroom", "kitchen", "bathroom"] of String

class Room
  def initialize(@type : String)
  end
end

class Map
  @map : Array(Array(Room))

  def initialize
    # Initialize the 2D array with SIZE inner arrays, each pre-sized to SIZE
    @map = Array.new(SIZE) { Array(Room).new(SIZE) }
    
    (0...SIZE).each do |i|
      (0...SIZE).each do |j|
        room_type = ROOMS.sample
        puts "Create a room '#{room_type}' at cell [#{i}, #{j}]"
        @map[i][j] = Room.new(room_type)
      end
    end
  end
end

Option 2: Build rows dynamically (avoids pre-allocation)

If you don't need to pre-allocate slots, build each row from scratch and add it to the main array:

class Map
  @map : Array(Array(Room))

  def initialize
    @map = [] of Array(Room)
    
    (0...SIZE).each do |i|
      row = [] of Room
      (0...SIZE).each do |j|
        room_type = ROOMS.sample
        puts "Create a room '#{room_type}' at cell [#{i}, #{j}]"
        row << Room.new(room_type)
      end
      @map << row
    end
  end
end

This approach eliminates index errors entirely because you're adding elements instead of assigning to pre-allocated (but possibly uninitialized) slots.


Key Takeaways

  • Crystal is statically typed: always initialize instance variables directly in initialize methods, and be explicit about types.
  • Use Array.new(size) { Array(T).new(size) } to create properly initialized 2D arrays—this avoids nil values and index errors.
  • Remember: double quotes for strings ("hello"), single quotes for single characters ('h').

内容的提问来源于stack exchange,提问作者siery

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 18:15:36