如果我们声明一个对象或函数而没有定义它,我们如何允许它在声明之前使用它以及如何在声明之前不允许它使用它? (对于在定义之前使用转发的声明结构标记的类似问题,基本上如何允许我们使用不完整类型以及如何不使用,请参阅https://stackoverflow.com/a/45725061/3284469)
声明是否出现在文件范围或块范围内是否重要?
如果其定义出现在相同或不同的翻译单元中,是否重要?
例如
getContacts() {
this.contactList.length = 0;
this.data.getAuthenticatedUserContactList().subscribe(
(contact => {
contact.map(userContact => {
this.contactList.push(<UserProfile>(userContact));
});
}),
(error => console.error(`getContacts Error: ${error}`))
);
}
getAuthenticatedUserContactList() {
return this.afAuth.getAuthUser()
.mergeMap(user => this.database.list(`contact-lists/${user.uid}`).take(1))
.mergeMap((contactList) => {
return Observable.forkJoin(contactList.map(element => this.getProfileWithUid(element.userId).map(userProfile => userProfile.val())))
});
}
getProfileWithUid(uid: string) {
this.profileObject = this.database.object(`/profiles/${uid}`, { preserveSnapshot: true });
return this.profileObject.take(1);
}
答案 0 :(得分:4)
声明一个对象是在其他地方提供定义的承诺。一旦声明了一个函数或一个外部变量,从那一点开始,你就可以做任何你可以对你定义的函数或变量做的事情。
声明的范围对你可以做什么没有影响,只能在代码中的位置进行。
在大多数情况下,代码转换器要求在链接代码时满足所有外部引用。否则,您会收到链接错误。
此规则的一个例外是在sizeof
表达式中使用声明的对象,该表达式不需要访问底层对象:
extern int undefined;
size_t res = sizeof(undefined);
上述内容不会破坏链接,因为sizeof
表达式不会生成对其参数的访问权。
答案 1 :(得分:0)
当你声明一个变量,一个函数,甚至是一个类时 做的是说:有这个名字的东西,它有这个 类型。然后编译器可以处理大多数(但不是全部)的用法 名称,不需要该名称的完整定义。 声明一个 value - 无需定义 - 允许您编写编译器的代码 可以理解,而不必把所有的细节。这是 如果您正在处理多个源文件,则特别有用 你需要在多个文件中使用一个函数。你不想放 多个文件中的函数体,但您确实需要提供 宣言。
extern int i;
这里,声明了整数类型变量i
(但是到目前为止没有定义,即变量i
没有内存分配)。我们可以根据需要多次进行此声明。
void fun();
函数fun()
声明,但未定义。但它确实告诉编译器它可以使用这个函数并期望它将被定义在某个地方。
答案 2 :(得分:0)
除了内联声明之外,您可以对声明执行任何操作。例如:
void fun();
inline void fun(){}
在声明之后,您可以调用该函数,除非该定义标记为inline
,在这种情况下,它将导致链接器错误,因为该定义不会发出要链接的符号。即使您没有明确说出inline
,如果已经看到定义,优化编译器也可以内联对该函数的调用。
答案 3 :(得分:0)
我在这里可以做些什么
用
extern int i;
i
可以根据程序的要求多次声明。 您可以拥有初始化程序
extern int i = 0;
我们在这里可以做些什么?
如果不在程序中定义,则无法使用i
。
extern int i;
int main(void)
{
i = 10; // Will through an error
return 0;
}
如果是函数,则此关键字仅表示该函数的链接为extern
。默认情况下,函数声明/定义的链接是extern。