Vala: Понимание свойств структуры в классах
В настоящее время я работаю над учебным пособием по Vala по адресу https://wiki.gnome.org/Projects/Vala/Tutorial. Теперь я наткнулся на один раздел, для которого мне нужно дополнительное объяснение; в части, посвященной свойствам объекта, в самом конце учебник знакомит со свойствами структуры. Приведен пример, который иллюстрирует, как получить такое свойство:
struct Color
{
public uint32 argb;
public Color() { argb = 0x12345678; }
}
class Shape: GLib.Object
{
public Color c { get; set; default = Color(); }
}
int main()
{
Color? c = null;
Shape s = new Shape();
s.get("c", out c);
}
В учебнике говорится: "Таким образом, c
является ссылкой вместо экземпляра Color on stack. Во что вы перешли s.get()
является Color **
вместо Color *.
"
Мой вопрос об утверждении выше. Во-первых, может кто-нибудь, пожалуйста, поясните, что подразумевается под "тем, что вы передали s.get()
является Color **
вместо Color *.
Кроме того, означает ли это, что следующее
int main()
{
Shape s = new Shape();
Color c = s.c;
}
приводит к значению s.c
быть назначенным на c
?
Изменить: я запустил приведенный выше пример в valac -C structs.vala
, Соответствующий С эквивалент main
метод
gint _vala_main (void) {
gint result = 0;
Color* c = NULL;
Shape* s = NULL;
Shape* _tmp0_ = NULL;
c = NULL;
_tmp0_ = shape_new ();
s = _tmp0_;
g_object_get ((GObject*) s, "c", &c, NULL);
result = 0;
_g_object_unref0 (s);
_color_free0 (c);
return result;
}
1 ответ
valac
компилирует код Vala в код C, который затем компилируется компилятором C (обычно GCC) в целевой формат (например, объектный файл, библиотеку или исполняемый файл).
Так о чем идет речь в руководстве Color**
является то, что сгенерированный код C будет проходить pointer to a pointer to a Color struct
к функции (которая является gobject_get
в сгенерированном коде C).
Структуры являются типами значений в C и в Vala *, что означает, что вся их память копируется при присваивании. Color?
в Вала nullable Color
) эквивалентно Color*
(а pointer to Color
) в с.
Вала переводит ref
а также out
параметры для указателей в C, так что вы получите двойной указатель (pointer to a pointer
) при вызове out
или же ref
параметр со значением NULL.
C менее строго типизирован, чем Vala, поэтому многие конструкции Vala в конечном итоге становятся указателями на C. C использует указатель для указания необязательных вещей, ссылок, параметров вызова по ссылке, массивов / строк, связанных списков и некоторых других более непонятные вещи (например, указатели функций и универсальные объекты).
Что касается вашего второго вопроса: копия будет сделана * при непосредственном присвоении переменной структуры.
* Смотрите этот вопрос с отличным ответом от AlThomas, который объясняет, когда происходит копирование на уровнях Vala и C.