引用当前实例的关键字:TclOO

Keyword for referencing the current instance : TclOO

我想知道这个 keyword 是否存在于 oo::class 中以符合 class 的成员资格?而不是 constructor 参数。喜欢 C#

中的关键字 this
public class Point2D
{
    private double X;
    private double Y;

    public Point2D(double x, double y)
    {
        this.X = x;
        this.Y = y;
    }
}

您希望 variable 命令声明一个“实例变量”。将 class 翻译成 TclOO,我会写

oo::class create Point2D {
    variable X
    variable Y

    constructor {x y} {
        set X $x
        set Y $y
    }
}

现在,您可以在方法中使用实例变量 $X$Y,无需进一步的语法或命令:

oo::define Point2D {
    # the distance from point (0, 0) to self
    method distance {} {
        return [expr {hypot($X, $Y)}]
    }
}

现在:

% set p [Point2D new 6 8]
% $p distance
10.0

延伸阅读:

您有多种选择。我最喜欢的是在 class 中使用 variable 声明 让变量只出现在方法中(包括构造函数和析构函数)。这也允许在幕后使用一些聪明的编译技巧,这实际上也使它变得相当快(尤其是当你开始获得很多方法时):

oo::class create Point2D {
    variable X Y

    constructor {x y} {
        set X $x
        set Y $y
    }
}

您还有其他选择。

这使用 variable 标准非导出方法(由 oo::object 提供),类似于使用 global 除了实例变量。

oo::class create Point2D {
    constructor {x y} {
        my variable X Y; # Needed in each method
        set X $x
        set Y $y
    }
}

标准的variable命令也可以完成这项工作;变量始终只是当前命名空间中的标准变量(8.7 及更高版本中的私有变量除外;那些使用 variable 无法处理的名称修饰)。

oo::class create Point2D {
    constructor {x y} {
        variable X
        variable Y
        set X $x
        set Y $y
        # The above four lines could have been the single line:
        #    variable X $x Y $y
        # but that's *very* specific to what this constructor is doing.
    }
}

另一个选项是 varname 非导出方法(又是 oo::class),它 returns 实例变量的完全限定名称。这不是这里的最佳选择,尽管它可以服务……但是对于与 vwait、Tk 小部件等一起使用非常有用

oo::class create Point2D {
    constructor {x y} {
        set [my varname X] $x
        set [my varname Y] $y
    }
}

正如您所想象的,最后一个选项是最慢的,因为它使用限定名称而不是能够更有效。 (我想你也可以通过扭曲事物来找到其他机制,但这些是我推荐的关键机制。)