1

このステイホーム期間中、私は TypeScript に飛び込むことに決め、いくつかの基本的なデータ構造を実装することでそれを実践し始めました。カスタム ノードを使用するカスタム スタックを実装しようとしています。

私の StackNodes は次のように定義されています。

class StackNode {

  private val: any;
  private nxt: StackNode | undefined = undefined;

  constructor(val: any, nxt?: StackNode | undefined) {
    this.val = val;
    this.nxt = nxt || undefined;
  }

  get value(): any {
    return this.value;
  }

  get next(): StackNode | undefined {
    return this.next;
  }

}

export default StackNode;


そして実際のスタック:

class Stack {

  private capacity!: number;
  private top?: StackNode | undefined = undefined;
  private size: number = 0;

  constructor(capacity: number, initialValues?: Array<any>) {
    this.capacity = capacity;

    if (initialValues) {
      this.size = initialValues.length;
      this.top = this._initStack(initialValues, initialValues.length - 1);
    }

  };

  private _initStack = (array: Array<any>, idx: number): StackNode => {
    if (idx == 0) {
      return new StackNode(array[idx], undefined);
    } else {
      return new StackNode(array[idx], this._initStack(array, idx-1));
    }
  }

  pop(): any {
    const value = this.top?.value();
    this.top = this.top?.next();
    return value;
  }

}

export default Stack;

ここでの問題は、pop-method のオプションの連鎖演算子の行です。this.top = this.top?.next()

私が理解したことは、式は次this.top?.next()と同等でなければならないということです

(this.top === null || this.top === undefined)? undefined : this.top.next()

しかし、私はまだエラーが発生します

おそらく「未定義」のオブジェクトを呼び出すことはできません.ts(2722)

その段階でもう未定義であってはならないにもかかわらず、呼び出しが行われたとき。

なぜですか?ここで何が欠けていますか?StackNode.nxt と Stack.top の両方を未定義にすることができます。私はこのような古い方法でそれをやろうとしました:

if (this.top !== null || this.top !== undefined) {
  const value = this.top.value()
  this.top = this.top.next()
}

しかし、私はまだ同じエラーをthis.top受け取ります.

これがどのように機能するかというと、空のスタックからポップすると pop メソッドは未定義を返し、最後の要素をポップすると、その次の未定義の要素がスタックの一番上に設定されます。

TS 3.8.3 を使用しています

4

1 に答える 1

1

next をゲッターとして定義するため、次のようにアクセスする必要があります。this.top = this.top?.next

コンパイルさえする唯一の理由const value = this.top?.value();は、「any」を使用しているためであり(DONT DO THAT、EVER !!)、typescriptは、get value呼び出している関数を返す可能性があると想定しています。

ジェネリックを使用して StackNode を定義する必要があります。例えば、

class StackNode<T> {

  private val: T;
  private nxt: StackNode<T> | undefined = undefined;

  constructor(val: T, nxt?: StackNode<T> | undefined) {
    this.val = val;
    this.nxt = nxt || undefined;
  }

  get value(): T {
    return this.value;
  }

  get next(): StackNode<T> {
    return this.next;
  }

}


class Stack<T> {

  private capacity!: number;
  private top?: StackNode<T> | undefined = undefined;
  private size: number = 0;

  constructor(capacity: number, initialValues?: Array<any>) {
    this.capacity = capacity;

    if (initialValues) {
      this.size = initialValues.length;
      this.top = this._initStack(initialValues, initialValues.length - 1);
    }

  };

  private _initStack = (array: Array<any>, idx: number): StackNode<T> => {
    if (idx == 0) {
      return new StackNode(array[idx], undefined);
    } else {
      return new StackNode(array[idx], this._initStack(array, idx-1));
    }
  }

  pop(): T | undefined {
    const value = this.top?.value(); //doesn't compile
    this.top = this.top?.next(); //doesn't compile either
    return value;
  }

}

その後、const value = this.top?.value();どちらもコンパイルされませんでした。

于 2020-04-05T18:00:36.090 に答える