2

我正在尝试使用 gnu-smalltalk。在以下带有变量的简单类的代码中,我发现它没有被初始化为给定值:

Object subclass: Myclass[
    |mainval|
    mainval := 555.
    getmainval [^mainval]
]

gc := Myclass new.
gc getmainval printNl.

该对象被创建而没有任何错误。但是,输出是:

nil

虽然我预计它会是 555。

如果我添加一个方法来为其赋值并在创建类的实例后调用它,它就可以工作。

问题出在哪里,如何纠正?谢谢。

4

1 回答 1

3

我认为您很接近,但是您尝试了一个不起作用的快捷方式,因为您期望在类定义中(在方法和本地有效性之外)将值设置为实例变量将返回值。实际上,您希望在方法中使用实例变量,例如init表达对象的内部状态。

正如我在之前的一些答案中所指出的,我不是 GNU Smalltalk 专家。我正在使用 Smalltalk/X-jv 分支进行编程。

我冒昧地将您的代码重写为更多类似 GNU Smalltalk 的代码:

Object subclass: MyClass [
    | mainVal |
    <comment:
        'testing main value'>
    MyClass class >> new [
        <category: 'instance creation'>
        | myClass |
        myClass := super new.
        myClass init.
        ^ myClass
    ]
    init [
        <category: 'initialization'>
        mainVal := 555.
    ]
    mainVal [
        ^ mainVal
    ]
]

说明:

我正在定义mainVal实例变量。然后我重新定义了一个不需要的类方法new但出于说明目的,我这样做了。(消息是从类继承的)newObject

我在类方法中正在做什么new。我将new消息发送到superclass创建实例的anObject,然后初始化myClasswithinit然后返回它。

之后,您可以看到将init您的实例变量初始化为您希望的值的类555

然后你有一个getter(在Smalltalk中通常没有get前缀,但那是“唯一”的风格问题)mainVal

然后你的代码调用对象并获取值。

gc := MyClass new.
gc mainVal

没有消息重新定义的最小示例:new

Object subclass: MyClass [
    | mainVal |
    <comment:
        'testing main value'>
    init [
        <category: 'initialization'>
        mainVal := 555.
    ]
    mainVal [
        ^ mainVal
    ]
]

您不能忘记,在 Smalltalk 中通常没有默认调用构造函数,因此您必须init手动发送消息(另一个选项是new像我上面所做的那样重新定义消息)。

然后使用它看起来像这样:

gc := MyClass new.
a MyClass
st> gc init
a MyClass
st> gc mainVal
555
于 2019-05-01T07:01:10.883 回答