我最近遇到了 this question 解释的 C 结构初始化示例.
我不明白的是什么似乎是递归定义;这是来自 MicroPython/objtype.c
typedef struct _mp_obj_type_t mp_obj_type_t;
const mp_obj_type_t mp_type_type = { // <-- SAME SYMBOL DEFINED HERE . . .
{ &mp_type_type }, // <-- IS USED HERE
.name = MP_QSTR_type,
.print = type_print,
.make_new = type_make_new,
.call = type_call,
.unary_op = mp_generic_unary_op,
.attr = type_attr,
};
.<some_field>
指定的字段我明白(请参阅第一句中的链接)。
但是关于“递归”初始化?
MicroPython code 中还有其他实例使用这种语法的:
const mp_obj_type_t pyb_led_type = {
{ &mp_type_type }, <-- SAME SYMBOL AS ABOVE
.name = MP_QSTR_LED,
.print = led_obj_print,
.make_new = led_obj_make_new,
.locals_dict = (mp_obj_t)&led_locals_dict,
};
这更有意义:结构 pyb_led_type
使用结构 mp_type_type
中设置的默认值进行初始化并且某些字段已从默认值更改。
但是const mp_obj_type_t mp_type_type
呢? ?
结构 mp_type_type
默认为 的值。 . .结构 mp_type_type
. . . ???
预处理后的输出与.c
相同.
这是怎么回事?
结构体的几个字段
struct _mp_obj_type_t {
// A type is an object so must start with this entry, which points to mp_type_type.
mp_obj_base_t base;
// The name of this type.
qstr name;
// Corresponds to __repr__ and __str__ special methods.
mp_print_fun_t print;
...
};
struct _mp_obj_base_t {
const mp_obj_type_t *type MICROPY_OBJ_BASE_ALIGNMENT;
};
typedef struct _mp_obj_base_t mp_obj_base_t;
最佳答案
C 中的自引用结构
您引用的 MicroPython 代码只是创建一个自引用结构实例,这在 C 中非常好。考虑这个示例,它几乎是您的示例,去掉了一些不必要的部分:
#include "stdio.h"
// const base
struct A {
const struct A* base;
};
// non-const base
struct B {
const struct B* base;
};
const struct A a = { &a };
const struct B b = { &b };
int main() {
printf("%p %p\n", (void*) &a, (void*)a.base);
printf("%p %p\n", (void*) &b, (void*)b.base);
return 0;
}
MicroPython代码中mp_obj_type_t
结构实例化的具体使用
MicroPython 项目使用 base
指针在 Python 中实现(多重)继承。 base
引用是指向另一个类型的指针,该类型是基类型(类型层次结构中的“父”),查看 definition of this struct :
struct _mp_obj_type_t {
// A type is an object so must start with this entry, which points to mp_type_type.
mp_obj_base_t base;
// .. many more fields
}
你提到的情况是 mp_type_type
const 变量似乎是所有类型的基类型,因此是自引用,但当你查看“继承”自的类型时它更有意义mp_type_type
,如pyb_led_type
:
const mp_obj_type_t pyb_led_type = {
{ &mp_type_type },
.name = MP_QSTR_LED,
.print = led_obj_print,
.make_new = led_obj_make_new,
.locals_dict = (mp_obj_t)&led_locals_dict, };
关于C 结构初始化完成 "recursively",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46184319/