【问题标题】:How do I invoke a recursive construtor in TypeScript?如何在 TypeScript 中调用递归构造函数?
【发布时间】:2018-12-30 16:24:08
【问题描述】:

我有一个类构造函数重载,我想根据提供的参数递归调用构造函数。

class Matrix {
    /**
     * Construct a new Matrix given the entries.
     * @param   arr the entries of the matrix
     */
    constructor(arr?: number[][]);

    /**
     * Construct a new Matrix given the size.
     * @param   rows the number of rows (matrix height)
     * @param   cols the number of columns (matrix width)
     */
    constructor(rows?: number, cols?: number);

    constructor(rows: number[][]|number = 0, cols: number = 0) {
        function isMatrixRaw(m: any): m is number[][] {
            // return `true` if m is of type number[][]
        }
        if (isMatrixRaw(rows)) {
            // ...
            // do all the main work here
            // ...
        } else { // typeof rows === 'number' && typeof cols === 'number'
            let m: number[][];
            // ...
            // create a 2D array of numbers, given rows and cols
            // recursively call the constructor with the new 2D array
            // ...
            new Matrix(m) // <-- is this right?
        }
    }
}

如果参数是二维条目数组,则主要构造函数的工作已完成,但我还想要一个重载:提供行大小和列大小(例如,new Matrix(2,3))。如果rowscols 是数字,我想创建一个二维数组,然后将该新数组传回构造函数。

递归构造函数调用如何在 TypeScript 中工作?我是打电话给new Matrix()return new Matrix()this.constructor()Matrix.constructor() 还是别的什么?

【问题讨论】:

  • 为什么不把二维数组的初始化放在前面,在rowsnumber[][]之后进行初始化的主要部分。 if (!isMatrixRaw(rows)) { rows = [[0]] } // do all the work after
  • @TitianCernicova-Dragomir 我不确定你的意思。我希望重载允许像 new Matrix(2,3) 这样的东西,然后创建像 [ [0,0,0], [0,0,0] ] 这样的数组并将其传递回构造函数。
  • 我的意思是这样的:stackblitz.com/edit/typescript-dkhurp
  • 您可以在构造函数中调用另一个递归函数并将这些参数传递给它,然后将结果返回给构造函数

标签: typescript recursion constructor overloading constructor-overloading


【解决方案1】:

您可以从构造函数返回一个值。返回值将是new 操作的结果:

class Matrix {
    public rows: number[][];
    constructor(arr: number[][]);
    constructor(rows: number, cols: number);
    constructor(rows: number[][]|number = 0, cols: number = 0) {
        function isMatrixRaw(m: any): m is number[][] { return m instanceof Array; }
        if (!isMatrixRaw(rows)) {
            // init rows with an array
            rows = new Array(rows).fill(0).map(_ => new Array(cols).fill(0));
            return new Matrix(rows);
        } else {
            this.rows = rows; // it's a number[][] now for sure
        }
    }
}

您可能会考虑重新组织您的代码,这样就不需要额外的调用。只需先进行检查,然后像使用 number[][] 完成调用一样完成大部分构造函数工作

class Matrix {
    public rows: number[][];
    constructor(arr: number[][]);
    constructor(rows: number, cols: number);
    constructor(rows: number[][]|number = 0, cols: number = 0) {
        function isMatrixRaw(m: any): m is number[][] { return m instanceof Array; }
        if (!isMatrixRaw(rows)) {
            // init rows with an array
            rows = new Array(rows).fill(0).map(_ => new Array(cols).fill(0));
        }
        this.rows = rows; // it's a number[][] now for sure
    }
}

【讨论】:

  • 请注意,您的第一个代码块将在 --strictNullChecks--strictPropertyInitialization 都打开时失败,因为 TS 没有检测到 this.rows 被设置在 if 子句中(即使我们知道它会通过递归)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
  • 2018-06-24
  • 1970-01-01
  • 2016-10-24
  • 1970-01-01
  • 2015-03-05
相关资源
最近更新 更多