微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用默认数组迭代器实现 Iterable 接口

如何解决使用默认数组迭代器实现 Iterable 接口

我有一个实现了Tuple的Vector类,像这样(简化代码,Tuple接口基本上就是一个没有方法的数组,固定大小N):

interface Tuple<T,N extends number> extends ArrayLike<T>,Iterable<T> {
    0: T
    length: N
}

export class Vector<N extends number> implements Tuple<number,N> {
    //Implementation
}

现在我想让我的 Vector 可迭代。当我创建一个 Tuple 类型的变量时,它已经是可迭代的,但 Vector 显然不是:

let t: Tuple<number,2> = [1,2]
for (const iterator of t) {...} //works

let v = new Vector([1,2])
for (const iterator of v) {....} //Type 'Vector<2>' must have a '[Symbol.iterator]()' method that returns an iterator.

我的问题是:如何将“认”迭代器实现到我的向量中,这样我就不必再次编写函数了?我可以以某种方式复制元组或数组迭代器吗? 如果这是不可能的,那么定义迭代器的最佳方法是什么?现在,我已将此(生成器)方法添加到我的 Vector 类中:

*[Symbol.iterator](): Iterator<number,any,undefined> {
       for (let i = 0; i < this.length; i++) {
           yield this[i]
       }
 }

它可以工作,但我不能 100% 确定它实际在做什么,返回值 Iterator 指定了什么,以及是否有更好的方法来做到这一点。

解决方法

如果你希望你的类是可迭代的,你肯定必须以某种方式提供一个迭代器。但是如果你只是想将迭代转发到你的类的一个属性,那么我认为你只需要实现一个 getter,从你想要迭代的任何东西中获取迭代器。

例如,类似于:

export class Vector<N extends number> implements Tuple<number,N> {
  constructor(public values: Tuple<number,N>) {}

  get [Symbol.iterator]() {
    return this.values[Symbol.iterator]
  }
}

现在当你迭代它时,你实际上是从内部属性 values 中获取迭代器,以进行迭代。

Playground


有没有办法在不保留“值”作为对象属性的情况下做到这一点(例如,通过直接在构造函数中分配 Symbol.iterator)?

当然。默认情况下,迭代器属性是只读的,但是如果您在类中声明迭代器类型,那么您就说它是可写的。然后赋值给构造函数中的迭代器属性。

class Vector {
  [Symbol.iterator]: () => Iterator<number>
  
  constructor(public values: number[]) {
    this[Symbol.iterator] = this.values[Symbol.iterator]
  }
}

See playground

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。