Пространства имён

В Ü есть механизм пространств имён, позволяющий структурировать содержимое программы. Каждое пространство имён имеет своё имя и может содержать в себе объявления а также вложенные пространства имён. Объявляются пространства имён с использованием ключевого слова namespace и {} скобок. Внутри скобок размещаются члены пространства имён. Допускается объявление нескольких пространств имён, новое объявление будет расширять старое пространство. Все пространства имён и другие сущности расположены так или иначе в глобальном пространстве имён или вложенных в него пространствах.

namespace A
{
    class SomeClass{ i32 x; }

    namespace Inner // Вложенное пространство имён.
    {
        fn Bar(i32 x);
    }
}

namespace A // Расширяем существующее пространство.
{
    fn AFunc();
}

namespace F
{
    class SomeClass{ f32 y; } // Класс с таким именем уже есть, но в другом пространстве имён, а значит не будет ошибки переопределения.
}

// Элементы глобального пространства имён.
struct S{}
fn Foo();

Разрешено объявлять сущности с одним и тем же именем в разных пространствах имён, в том числе в родительском и в дочернем. В последнем случае имя из дочернего пространства будет перекрывать имя из родительского пространства.

Поиск имён

При встрече имени происходит поиск символа с данным именем. Поиск начинается в текущем пространстве имён и продолжается на его родительские пространства, пока соответствующее имя не будет найдено.

namespace A
{
    namespace B
    {
        struct S{}
        namespace C
        {
             fn Foo()
             {
                 var S s; // Будет найдено имя A::B::S
             }
         }
     }
}

Для выборки имён из конкретных пространств существует способ конкретизировать имя - указать частичный его адрес с :: разделителем. В этом случае произойдёт сначала поиск подходящего пространства, указанного в начале конкретизированного имени, по правилам описанным выше, затем произойдёт выборка имени с использованием дальнейших его компонентов. Для указания полного адреса имени, начиная с глобального пространства имён, следует начать адрес с ::.

namespace A
{
    struct S{}
    namespace B
    {
        struct S{}
        namespace C
        {
             fn Foo()
             {
                 var A::S s0; // Будет найдено имя A::S
                 var B::S s1; // Будет найдено имя A::B::S
                 var A::B::S s2; // Будет найдено имя A::B::S
                 var ::A::S s3; // Будет найдено имя A::S
                 var ::A::B::S s4; // Будет найдено имя A::B::S
             }
         }
     }
}

Дополнительные виды пространств имён

Структуры, классы, перечисления тоже являются пространствами имён. К их членам можно обращаться извне с использованием имени структуры/класса/перечисления и :: для указания внутреннего элемента.

struct S
{
    type Int= i32;
}

class C
{
    fn Bar();

    struct F
    {
        type FT= f64;
    }
}

enum E
{
    R,
    G,
    B,
}

fn Foo()
{
    var S::Int i= 0; // Обращение к псевдониму типа - члену структуры.
    C::Bar(); // Обращение к функции - члену класса.
    var C::F::FT f= 0.0; // Обращение к псевдониму типа - члену структуры, вложенной в класс.
    var E e= E::G; // Обращение к члену перечисления.
}