Статическая инициализация и использование класса в отдельном модуле в D

В моей программе есть класс, который я хочу выделить перед входом в main(). Я хотел бы спрятать их в отдельный модуль, чтобы не загромождать свой код; Однако, как только модуль выходит из области видимости (до ввода main()), объекты освобождаются, и я пытаюсь использовать нулевую ссылку в main. Краткий пример:

// main.d

import SceneData;

int main(string[] argv)
{
    start.onSceneEnter();

    readln();
    return 0;
}

// SceneData.d

import Scene;

public
{
    Scene start;
}

static this()
{
    Scene start = new Scene("start", "test", "test";
}

// Scene.d

import std.stdio;

class Scene
{
    public
    {
        this(string name)
        {
            this.name = name;
        }

    this(string name, string descriptionOnEnter, string descriptionOnConnect)
    {
        this.name = name;
        this.descriptionOnEnter = descriptionOnEnter;
        this.descriptionOnConnect = descriptionOnConnect;
    }

        void onSceneEnter()
        {
            writeln(name);
            writeln(descriptionOnEnter);
        }
    }

    private
    {
        string name;
        string descriptionOnEnter;
        string descriptionOnConnect;
    }
}

Я все еще привыкаю к ​​тому, что модули являются базовой единицей инкапсуляции, в отличие от класса в C++ и Java. Возможно ли это сделать в D, или я должен перенести свои инициализации в основной модуль?


person Meta    schedule 25.01.2012    source источник
comment
Ваш код работает. Ваша проблема скорее всего в другом.   -  person Vladimir Panteleev    schedule 25.01.2012


Ответы (1)


Здесь:

static this()
{
    Scene start = new Scene("start", "test", "test");
}

«start» — это локальная переменная области видимости, которая скрывает глобальную. Глобальный не инициализирован. После того, как я изменил это на:

static this()
{
    start = new Scene("start", "test", "test");
}

Программа больше не вылетала.

person Mihails Strasuns    schedule 25.01.2012
comment
Ах, вот оно. Забавно, как такое незначительное упущение могло вызвать такую ​​досадную ошибку. Я думаю, именно поэтому глобалы — это плохо. - person Meta; 25.01.2012
comment
Вероятно, стоит подать запрос на улучшение, чтобы выдать предупреждение в случае затенения глобальной переменной локальной. Хотя не уверен, что это вообще хорошая идея. - person Mihails Strasuns; 25.01.2012
comment
Разрешение затенения глобальных переменных сделано намеренно. Вы бы не хотели, чтобы ваш код прерывался, потому что импортированный модуль добавил новую глобальную переменную с тем же именем, что и одна из ваших локальных переменных. Если вы хотите специально получить доступ к затененной переменной, добавьте к ней префикс .. - person Jonathan M Davis; 26.01.2012
comment
Да, именно это заставило меня усомниться — слишком нормально, чтобы быть предостерегающим. Я чувствую, что обычной схемы предупреждение-ошибка на самом деле недостаточно, так как предупреждения в любом случае чаще всего рассматриваются как ошибки. Что-то вроде подсказки в отдельном режиме статического анализа? Проблема в том, что эту ошибку легко совершить, но довольно сложно заметить новичку. И я чувствовал, что философия D как раз и состоит в том, чтобы максимально предотвратить такие сценарии. - person Mihails Strasuns; 26.01.2012
comment
Затенение глобального объекта в том же модуле, OTOH, может быть поводом для принятия мер. - person BCS; 27.01.2012