怎么实现 Vector[T]?

现在貌似无法实现 Vector[T],缺少类型的默认值,以及 array_make[T]

struct Vector[T] {
  data: Array[T]
  len: Int
  cap: Int
}

func new[T]() -> Vector[T] {
  {
    data: array_make(8, T::default()),
    len: 0,
    cap: 8,
  }
}

1 个赞

大家可以参见 https://try.moonbitlang.com/ 的 017_vector.mbt 例子,大致如下:

struct Vector[X] {
  mut data : Array[X]
  mut len : Int
}

/// `print[X : Show](self : Vector[X])`
///
/// Print a vector, type inside the vector must have method `to_string`

func print[X : Show](self : Vector[X]) -> Unit {
  var i = 0
  "[".print()
  while i <= self.length() {
    match self[i] {
      Some(x) => { x.to_string().print(); " ".print() }
      None => "]\n".print()
    }
    i = i + 1
  }
}

/// `length[X](self : Vector[X])`
///
/// Get length of a vector
func length[X](self : Vector[X]) -> Int {
  self.len
}

/// `capacity[X](self : Vector[X])`
///
/// Get capacity of a vector
func capacity[X](self : Vector[X]) -> Int {
  self.data.length()
}

/// `Vector::new_with_default[X](len : Int, default : X)`
///
/// Create a vector with length `len`, filling with value `default`
func Vector::new_with_default[X](len : Int, default : X) -> Vector[X] {
  { data: array_make(len, default), len }
}

/// Vector::new[X : Default](len : Int)
///
/// Create a vector with length `len`, filling with default value of type `X`
func Vector::new[X : Default](len : Int) -> Vector[X] {
  Vector::new_with_default(len, X::default())
}

/// `op_get[X](self : Vector[X], i : Int)`
///
/// Get the ith element of vector
func op_get[X](self : Vector[X], i : Int) -> Option[X] {
  if i < self.len {
    Some(self.data[i])
  } else {
    None
  }
}

/// push_back_with_default[X](self : Vector[X], elem : X, default : X)
///
/// Push back `elem` to a vector, `default` will be used to fill the additional space
func push_back_with_default[X](self : Vector[X], elem : X, default : X) {
  if self.len < self.capacity() {
    self.data[self.len] = elem
    self.len = self.len + 1
  } else {
    let old_cap = self.capacity()
    let new_cap = if old_cap == 0 {
      10
    } else {
      old_cap * 2
    }
    let new_data = array_make(new_cap, default)
    var i = 0
    while i < self.len {
      new_data[i] = self.data[i]
      i = i + 1
    }
    new_data[self.len] = elem
    self.data = new_data
    self.len = self.len + 1
  }
}

/// push_back[X : Default](self : Vector[X], elem : X)
///
/// Push back `elem` to a vector, default value of type `X` will be used to fill the additional space
func push_back[X : Default](self : Vector[X], elem : X) {
  self.push_back_with_default(elem, X::default())
}

struct T {
  x : Int
}

func to_string(self : T) -> String {
  "{x: " + self.x.to_string() + "}"
}

func T::default() -> T {
  { x: 0 }
}

func init {
  let v1 : Vector[Int] = Vector::new(5)
  v1.print()
  v1.push_back(42)
  v1.print()
  let v2 : Vector[T] = Vector::new(5)
  v2.print()
  v2.push_back({ x: 42 })
  v2.print()
}