c++error undefined reference errorto `Student::classSize'

我曾经在ubuntu14.04上用PYTHON_LAYER:=1成功编译caffe然后我切换到Ubuntu16.04,使用相同的设置但不同的内置软件比如16.04版的g++5.4版,而不是14.04版的g++4.8版我无法用python编译caffe。你能就这个问题给我一些建议吗以下是我收箌的错误消息的一部分


TypeScript是JavaScript语言的一个类型化超集是由微软开发的免费、开源编程语言。其本质上是向JavaScript添加了一些可选的静态类型和基于类的面向对象编程特性可编译为原生JavaScript语言。目前为止筆者仍认为学TypeScript是非必须的但不可否认有很多npm模块都在使用或转为使用TypeScript开发,因此有必要学习和掌握这一语言扩展

本文是非官方的TypeScript中文攵档,基于翻译和整理请结合及相关版本参阅本文。

= 如果两者都需要,则必须使用箭头函数:

如果不想在使用模块前花时间编写模块聲明则可以简写声明以便快速使用。

/ponent定义为有两个参数PropsState。在一个.js文件中没有合法的extends语句指定方式。默认参数类型为any


可以通过JSDoc的@augments參数来指定类型例如:

    

JSDoc中未指定类型的参数默认为any

    

对泛型函数的调用使用arguments来推断类型参数。有时这一过程无法推断出类型,主要是洇为缺少推断源;在这些情况下类型参数将默认为any。例如:

    


下面的列表列出了当前支持的JSDoc注释你可以JavaScript文件中通过它们来提供类型。
请紸意列表中没列出的标签都还不支持(如:@async)。

它们所表示的含义与usejsdoc.org中给出的标记的含义相同或者是一个超集。下面的代码描述了它們的区别并给出了每个标签的一些用法示例。

可以使用@type标记并引用类型名称(在TypeScript声明或JSDoc@typedef标记中定义的原始类型)可以使用任何Typescript类型以忣大多数JSDoc类型。

有多种方式来指定数组类型:

还可以指定对象字面量类型如,一个有a(字符串)和b(数字)属性的对象使用如下语法:

可以使鼡标准的JSDoc语法或TypeScript语法,使用字符串和数字索引签名指定类似Map的对象和类似于数组的对象

或者可以直接使用Function类型。

Closure中的其它类型也可以使鼡:

TypeScript借签了Closure中的强制转换语法可以通过在任何带括号的表达式之前添加@type标记,将类型转换为其他类型


也可以使用导入类型从其它文件導入声明。此语法是TypesSript特有的并且与JSDoc标准不同:

导入类型也可以类型别名声明中使用:

如果不知道导入类型,或者如果导入的类型不易识別则可以使用导入类型从模块获取值的类型:

    

@param的语法与@returns相同,但增加了一参数名使用[]可以把参数声名为可选的:

函数的返回类型也类姒:

    

@typedef可以用来声明复杂类型,语法与@param类似

    

@param允许使用类似的语法。注意嵌套的属性名必须使用参数名做为前缀:

@callback@typedef相似,但它可以指定函数类型而不是对象类型:

当然所有这些类型都可以使用TypeScript的@typedef语法在同一行上声明:

    

通过@template标签声明泛型类型:

使用逗号或多个标签来声明哆个类型参数:

还可以在类型参数名称之前指定类型约束。仅列表中第一个类型参数受约束:
 

编译器会根据this属性的赋值来推断构造函数泹可以添加@constructor标记以使检查更严格、提示更完善:

通过@constructor,会在构造函数C中检查this因此你会在initialize方法中得到一个提示,如果传递给它一个数字則会得到一个错误。如果直接调用C而不是构造它也会收到错误。
不幸的是这意味着那些即能构造也能直接调用的构造函数不能使用@constructor

通常编译器可以根据上下文来推断this的类型但可以通过@this来指定其类型:

    

当Javascript类扩展通用基类时,没有地方指定类型参数的类型@extends标记为该类型参数提供了一个位置:

注意,@extends仅适用于类当前,构造函数无法扩展类

@enum使你可以创建对象字面量,其类型都是确定的类型与JavaScript中的大哆数对象字面量不同,它不允许添加额外成员

    

    


    

    

13. 已不支持的模式


除非对象也创建类型(如:构造函数),否则在值空间中将对象视为类型昰不可以的

对象字面量上的属性类型上的=后缀不能指定这个属性是可选的:

    

非空类型没有意义,它们被当作原始类型对待:

与JSDoc的类型系統不同TypeScript仅允许将类型标记为包含null或不包含null。没有显式的不可为空性—如果strictNullChecks启用则number不可为空。如果关闭则number可以为空。


    

自标准化以来的20哆年来JavaScript已经走了很长一段路。尽管在2020年JavaScript可以在服务器、数据科学甚至IoT设备上使用,但请记住其最流行的用例:Web浏览器

网站由HTML和/或XML文檔组成,这些文件是静态的它们不会变动。文档对象模型(DOM)是由浏览器实现的编程接口目的是使静态网站正常运行。DOM API可用于修改文檔结构、样式和内容该API非常强大,以至于围绕它开发了很多的前端框架(jQueryReactAngular等)以使动态网站的开发更加容易。

关于DOM类型定义的源碼请参考:

以下是一个简单的index.html文件:

编译并运行index.html页面,结果为:

向其传递元素的ID它会返回HTMLElementnull。此方法中引用了最重要的类型之一HTMLElement它會充当所有其它元素接口的基础接口。例如示例中的p变量的类型为HTMLParagraphElement。另外需要注意此方法可以返回null。因为如果该方法是否能够找到指定的元素,其无法在运行前确定示例代码中的最后一行,使用了新的可选链接运算符来调用appendChild

这是一个重载的函数定义。第二次重载非常最简单并且类似于getElementById方法。向其传递任何string其会返回标准的HTMLElement。此定义使开发人员能够创建唯一的HTML元素标签

对于createElement的第一个定义,它使鼡了一些高级通用模式最好将其按块分解。从通用表达式开始:<K extends keyof HTMLElementTagNameMap>该表达式定义了一个通用参数K,该参数被限制于HTMLElementTagNameMap接口的键中映射接ロ包含每个指定的HTML标记名称及其对应的类型接口。例如这是前5个映射值:

有些元素没有唯一的属性,因此它们仅返回HTMLElement而其他类型的确具有唯一的属性和方法,因此它们返回其特定的接口(会从HTMLElement扩展或实现)

HTMLElementTagNameMap[K]。第一个参数tagName定义为通用参数KTypeScript解释器足够聪明,可以从此参數推断出通用参数这意味着开发人员在使用该方法时并不需要指定泛型参数。传递给tagName参数的任何值都将推断为K所以可以在定义的其余蔀分中使用。那么发生了什么;返回值HTMLElementTagNameMap[K]使用tagName参数,并使用它返回相应的类型

该方法与createElement方法的工作方式类似,因为从newChild参数推断出通用参數TT被限制为另一个基本接口Node

以前文档详细介绍了HTMLElement接口,该接口从Element扩展而ElementNode扩展。在DOM API中有子元素的概念。例如在以下HTML中,p标签昰div元素的子元素:

通过删除p标签之修改html但保留文本。

这两种方法都是获取适合dom元素列表的出色工具它们在lib.dom.d.ts中定义为:

=> void)和数字索引。另外方法会返回元素列表,而不是节点列表这是NodeList.childNodes方法返回的内容。虽然这看起来可能有所差异但要注意接口Element从Node扩展。

查看这些方法嘚实际应用请将代码修改为:

lib.dom.d.ts类型定义的好处在于,它们反映了Mozilla(MDN)文档中注释的类型例如,MDNHTMLElement页面关于HTMLElement接口的说明这些页面列出了所有可用的属性、方法,甚至还列出了示例 这些页面的另一个重要方面是它们提供了指向相应标准文档的链接。参考:

letconst是JavaScript中两种相對较新的变量声明类型。正如我们前面提到的let在某些方面类似于var,但是使用户可以避免在JavaScript中遇到的一些常见“陷阱”

constlet的增强,因为咜可以防止重新给变量赋值

由于TypeScript是JavaScript的扩展,因此该语言自然支持letconst在这里,我们将详细说明这些新声明及为什么它们比var更可取

如果伱直接使用过JavaScript,那么本节可能是刷新认知的好方法如果你对JavaScript中的var声明的所有怪癖都非常熟悉,则可以跳过本节

在传统的JavaScript中声明变量始終使用var关键字:

如上所示,我们刚刚声明了一个名为a的变量其值为10

我们还可以在函数内部声明变量:

还可以在内部函数中访问相关的變量:

以上我们在f函数中定义了一个变量a,该变量在函数g的任何位置都可以访问即使在f完成运行后调用g,它也将能够访问和修改a

var声奣相对于其他语言使用的规则有一些奇怪的作用域规则。请看以下示例:

在这个示例中变量xif块内声明,但是我们仍然可以从该块外部訪问它这是因为var声明可在其包含函、模块、命名空间或全局范围内的任何位置访问。有人将其称为var 作用域函数作用域参数也在函数范圍内。

这些范围规则可能会导致几类的错误尤其是多次声明相同的变量不是错误,会导致问题加剧:


以上示例中内部的for循环会意外覆蓋变量i,因为i引用是同一作用域变量

快速猜测以下代码段的输出是什么:

不熟悉的人可能会认为,setTimeout会在指定时间后执行一个函数
其实,其输出是这样的:

许多JavaScript开发人员都非常熟悉这种行为但大多数人期望输出是:
0
 

正如前面提到的有关变量捕获的内容所说。我们传递给setTimeout嘚每个函数表达式实际上都来自同一作用域中的相同i
也就是说,setTimeout将在几毫秒后运行一个函数但是仅在for循环停止执行之后;到for循环停止執行时,i的值为10因此,每次调用指定的函数时其都会输出10
常见的解决方法是使用IIFE(立即调用函数表达式,也就闭包)在每次迭代中捕获i

这种看起来很奇怪的模式实际上很常见参数列表中的i实际上会覆盖在for循环中声明的i,但是由于我们将它们命名为相同的名称从洏不必对循环体进行太多修改。


到此你已经发现了var存在一些问题,这就是为什么引入let语句的原因除了所使用关键字不同外,let语句的编寫方式与var语句的编写方式相同

关键区别不在于语法,而在于语义接下来我们将深入探讨语义。

当使用let声明一个变量时它使用词法作鼡域或块级作用域。与用var声明的变量的范围泄漏到其包含函数不同在其最近的包含块或for循环之外块作用域变量不可见。

在这里我们定義了ab两个局部变量。a的作用范围仅限于f的函数主体而b的作用范围仅限于其被包含的if语句块。
catch子句中声明的变量也有类似的作用域规則

块范围变量的另一个特性是,在实际声明它们之前不能对其进行读写。尽管这些变量在其整个范围内都“存在”但直到声明它们の前的所有时间点都不可见。也就是说你不能在let语句之前访问它们

需要注意的是,你仍然可以在声明之前捕获块范围的变量唯一的问題是在声明之前调用该函数是非法的。如果是在ES2015中则会引发运行时错误;但是,在TypeScript中是允许的因此不会将其报告为错误。

更多相关信息请参考:。

对于var声明声明变量多少次无关紧要,你只会得到一个

在上面的示例中,x的所有声明实际上都引用相同的x这是完全有效的。这通常会成为错误的来源而x声明并不会那么宽容。

并不需要TypeScript都对变量进行块作用域分析以告诉我们存在问题。

这并不是说永远鈈能使用函数范围的变量来声明相同的块范围的变量只需在明显不同的块中声明块范围的变量。

在更嵌套的范围内引入新名称的行为称為阴影(shadowing)它像一把双刃剑,因为它可能在意外阴影的情况下自行引入某些错误同时还可以防止某些错误。例如假设我们已经使用let变量萣义了更早的sumMatrix函数。

这一版本的循环实际上将正确执行求和因为内部循环的i屏蔽了外部循环中的i
为了使编写的代码更清晰通常应避免阴影。虽然在某些情况下可以利用它但是你应该有一个最佳的判断。

当我们第一次谈到使用var声明变量进行捕获时我们简要地介绍了變量被捕获后的行为。为了更好地理解这一点每次运行时,都会创建变量的“环境”该环境及其捕获的变量,即使在其范围内的所有內容完成执行之后也可以存在

由于我们是从运行环境中捕获city的,因此尽管if块已完成执行我们仍然可以访问它。
回想一下在我们前面嘚setTimeout示例中,最终需要使用IIFE来为for循环的每次迭代捕获变量的状态实际上,我们是为所捕获的变量创建一个新的变量环境这有点痛苦,但昰幸运的是在TypeScript中不必再这样做。
当声明为循环的一部分时let声明的行为会大不相同。
这些声明不仅为循环本身引入了新的环境还为每佽迭代创建了新的作用域。由于无论如何我们都是通过IIFE进行此操作因此我们可以将旧的setTimeout示例更改为仅使用let声明。

这将会符合预期的输出洳下:
0
 

    
 

 

const是另一种变量声明方法
 

它与let声明类似,但是顾名思义,绑定后就无法更改其值也就是说,它们具有与let相同的作用域规则但昰无法对其重新赋值。
但这并是说它们所引用的值是不可变的
 

除非通过特定措施来避免,否则const变量的内部状态仍是可以修改的而TypeScript允许伱指定对象的成员为readonly。相关详细信息请参见
 

 

由于有两种类似范围语义的声明,很自然地你会问自己应使用哪一种这时应该根据具体情況来判断。
根据除计划修改的那些声明外,所有其他声明都应使用const这样做的理由是,如果不需要写入变量则在同一代码库上工作的其他人不应能够写入该对象,并且需要考虑是否确实需要将其重新分配给该变量使用const还可以在推断数据流时使代码更可预测。
 

 

TypeScript有另一个ECMAScript 2015嘚功能是“解构”相关的完整参考,请参阅在本节中,我们会简要概述
 
 

解构的最简单形式是数组解构分配:
 

这将创建两个名为firstsecond的噺变量。这与使用索引等效但是更加方便:
 

解构也可以使用已经声明的变量:
 

也可以在函数参数中使用:
 

还可以使用...(剩余操作符)语法为数组中的剩余项目创建变量:
 

因为是JavaScript,因此可以忽略不需要的尾随元素:
 

    
 

    
 
 

元组可以像数组一样被解构;解构变量会获取相应的元组元素的类型:
 

解构超出元组元素范围会引发错误:
 

与数组一样可以使用...来解构其余的元组,以获得较短的元组:
 

或忽略尾随元素或其他元素:
 

    
 
 

    
 

这会从o.ao.b创建新的变量ab请注意,如果不需要可以跳过c
像数组解构一样可以直接赋值而无需声明:
 

注意,必须用括号将这个語句括起来JavaScript通常会将{解析为块的开始。
你可以使用以下语法为对象中的其余项创建变量:
 

可以为属性指定一个不同的名称:
 

    
 

令人困惑的昰这里的冒号并没有指定类型。如果指定了类型则在整个解构之后仍需要编写类型:
 

默认值可以在属性未定义时指定一个默认值:
 

在這个示例中b?表示b是可选的,因此可能是不确定的keepWholeObject现在有一个用于wholeObject的变量以及属性ab,即使b未定义
 
 

解构同样可用于函数声明:
 

但对于参數而言,指定默认值更为常见并且通过解构正确获取默认值可能比较难处理。首先需要记住将模式放在默认值之前:
 

然后,你需要记住为非结构化属性(而不是主初始化程序)提供可选属性的默认值请记住,C是使用可选的b定义的:
 

应小心使用解构如前面的示例所示,除了最简单的解构表达式之外其他任何东西都令人困惑。对于深度嵌套的解构尤其如此即使不依赖重命名、默认值和类型注释,也佷难理解尝试使解构表达式小而简单。 您总是可以编写解构会产生自己的任务
 

 

展开操作(spread)与解构相反它允许你将一个数组散布到另一个數组中,或将一个对象散布到另一个对象中例如:
 

这使bothPlus的值为[0、1、2、3、4、5]。展开会创建firstsecond的浅复制副本其自身不会因展开而改变。
 

现茬search{ food: "rich", price: "$$", ambiance: "noisy" }对象展开比数组展开更复杂。 像数组展开一样它是从左到右进行,但是结果仍然是一个对象这意味着,在展开对象中位于后面嘚属性将覆盖之前的属性因此,如果我们修改前面的示例以在最后展开:
 

这时food属性会被defaults中的值重写。在本例中这并不是我们所期望嘚。
对象展开还有一些限制首先,它仅包含对象自己的可枚举属性这意味着你在展开对象实例时会丢失方法:
 

其次,TypeScript编译器不允许泛型函数展开类型参数该功能将在未来版本中提供。
 
 

不明确的运算需要用括号括起

包含命令中文件名格式不正确

调用函数时没有函数的说明

代码不可述不可能执行到

我要回帖

更多关于 reference error 的文章

 

随机推荐