文章目录

  • 1. GO语言OOP概述
  • 2. 封装的实现
    • 封装的实现
  • 3. 继承的实现
  • 4. 多态的实现
    • 4.1 接口概述
    • 4.2 声明接口
    • 4.3 实现接口
    • 4.4 接口嵌套
    • 4.5 类型断言的格式
    • Go语言中的switch可以做的类型断言
    • 4.6 空接口类型 interface{}
    • 4.7 如何实现多态
      • 实现多态方法1:
      • 实现多态方法2:

1. GO语言OOP概述

Go语言不是纯粹的面向对象的语言,准确是描述是,Go语言支持面向对象编程的特性.
Go语言中没有传统的面向对象编程语言的 class ,而Go语言中的 struct 和 其他编程语言中的 class 具有同等地位,也就是说Go语言是 基于 struct 来实现 OOP 的特性的
面向对象编程在Go语言中的支持设计得很具有特点,Go语言放弃了很多面向对象编程的概念,如 继承,重载, 构造函数, 析构函数 ,隐藏this指针等
Go语言可以实现面向对象编程的特性 封装 , 继承, 多态
Go语言面向对象编程的支持是语言类型系统 中天然的组成部分,整个类型系统通过接口串联,灵活度高
面向对象编程OOP的三大基本特征是封装 继承 和多态 Go语言支持面向对象编程,但是它实现面向对象的方式与其他语言不同,Go语言中没有private , protected , public 等对成员属性或者方法进行可见性描述的关键字 , 没有继承这个字面的概念也不存在多继承的概念等等,但是Go语言通过自身语言特点实现了对OOP的支持,关于这点我们看到在一些资料中提到了 duck typing 的概念,

When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck
一只鸟走路像鸭子,游泳像鸭子叫声也像鸭子,那我们就可以称它是鸭子

通过对Go语言的学习,一些我们很模糊的概念都会清晰的

2. 封装的实现

封装是将抽象出来的字段或者属性和对字段属性的操作封装在一起,其他程序只能通过授权的方法才能对其进行操作,Go语言在开发中不是很强调封装的特性.无需纠结与其他语言不同的方面.

封装的实现

包内成员入定义的变量或者方法或者函数首字母小写,仅在包内可见,包外不可见
结构体,字段属性的的首字母小写决定其对外不可见
为结构体所在的包提供一个构造函数
提供一些可以设置私有属性的方法对外可见
提供一些可以获取属性的方法对外可见
示例

// 文件结构如下
|__model
|____person.go
|__main.go

person.go

package model// 这是一`私有`person 类型结构体
// 包外不能直接生生成一个该类型的实例
// person 首字母小写包外不见
type person struct {// 首字母大写保外可见Name string// 首字母小写保外不可见age     int8Work    stringdeposit float64hobbys  []string
}// 构造函数
// 包外可见
func NewPerson(name string, age int8, work string, deposit float64) *person {return &person{Name:    name,age:     age,Work:    work,deposit: deposit,}
}// 给person类型数据添加各种方法
func (p *person) GetAge() int8 {return p.age
}
func (p person) GetDeposit() float64 {return p.deposit
}
func (p *person) SetHobby(h string) {p.hobbys = append(p.hobbys, h)
}
func (p person) GetHobbys() []string {return p.hobbys
}

main.go

package mainimport ("GoNote/chapter6/demo18/model""fmt"
)func main(){// 定义一个结构体变量p1p1 := model.NewPerson("tom",26,"UI",50000.01)fmt.Println(p1)// 只能访问可见属性, 成员属性age和deposit是访问不到的fmt.Println(p1.Name,p1.Work)// 通过可见方法访问不可见的属性fmt.Println(p1.GetAge())fmt.Println(p1.GetDeposit())// 调用设置的方法(*p1).SetHobby("跑步")p1.SetHobby("爬山")// 嗲用获取的方法fmt.Println(p1.GetHobbys())
}
go run main.go
&{tom 26 UI 50000.01 []}
tom UI
26
50000.01
[跑步 爬山]

3. 继承的实现

Go语言的继承是通过组合的方式实现的.

结构体中内嵌了只有类型没有名称的结构体的时候我们称之为内嵌了匿名结构体
结构体总内嵌的结构体既有名字也有类型,这种模式我们称为 组合
Go语言的结构体内嵌特性就是一种组合,使用组合可以快速构建对象的不同属性

package mainimport "fmt"// 定义一个Good结构体
type Good struct {name        stringproductDate stringprice       float64
}// 定义一个Books结构体
type Books struct {// 内嵌Good类型的结构体Good// Books自由的成员字段classify   stringpublishing stringauthor     string
}// 定义Vendor结构体
type Vendor struct {VendorName  stringretailPrice float64grade       float32
}// 定义ProgrammingBook 的结构体
type ProgrammingBook struct {// 构成组合// 此处类似于多继承b        Booksv        Vendoroverview stringchapters []string
}// 给Good类型绑定一个方法
func (g *Good) setGoodInfo(name string,pd string,price float64) {g.name = nameg.productDate = pdg.price = price
}
func (g *Good) GoodDescribe() string {return fmt.Sprintf("商品名称是%s,价格是%.2f,生产日期是%s\n", g.name, g.price, g.productDate)
}// 给Books绑定一个BasicInfo的方法
func (b *Books) booksDescribe() string {return fmt.Sprintf("书的分类是%s,出版商是%s,作者是%s\n", b.classify, b.publishing, b.author)
}
func (p *ProgrammingBook) GetBook() {//可以调用ginfo := p.b.GoodDescribe()binfo := p.b.booksDescribe()fmt.Printf("商品信息 :%s 书籍信息 :%s 书籍概览 :%s",ginfo,binfo,p.overview)
}
func main() {var gobook ProgrammingBook// 结构体变量Gobook 内嵌了 Books类型结构体,Books结构体又和Good是组合的//不是很严谨的说法:相当于ProgrammingBook 继承 Books ,Books继承了Good , 那么ProgrammingBook也继承Good的属性和方法// 所以ProgrammingBook的实例 gobook能调用Good的方法gobook.b.setGoodInfo("Go程序设计语言","2019-10-01",99.90)// ProgrammingBook结构体内嵌了有名结构体Books,Vendor(组合),相当于继承了他们属性和方法gobook.b.classify = "计算机|编程"gobook.b.publishing = "机械工业出版社"gobook.b.author = "艾伦 A.A.多诺万"gobook.v.VendorName = "当当网"gobook.v.retailPrice = 89.0gobook.v.grade = 9.2gobook.overview = "号称Go语言界的圣经"gobook.GetBook()}
go run main.go

商品信息 :商品名称是Go程序设计语言,价格是99.90,生产日期是2019-10-01
书籍信息 :书的分类是计算机|编程,出版商是机械工业出版社,作者是艾伦 A.A.多诺万
书籍概览 :号称Go语言界的圣经

对结构体组合的补充描述

无论匿名的内嵌的匿名结构体还是组合,各个结构体中有相同的结构体字段,那么访问遵循就近原则 , 就近原则无效的时候,匿名内嵌的必须通过结构体类型访问该字段,组合的必须通过 结构体名(类似别名),去访问
给不同的类型添加方法时方法名可以相同.前提是接收器不能相同
结构体内嵌多个结构体会出现多继承 的特点
出现多层级的内嵌结构体如 : A内嵌在B中,B内嵌在C中,C内嵌在D中,D内嵌在E中 … 无论是想访问结构体属性(字段) 或者是调用方法,只需要正确的指向那个结构体,就可访问成员属性和调用方法

package mainimport "fmt"type AA struct {name stringAAAddr string
}
type BB struct {name stringBBAddr string
}
type DD struct {name stringDDAddr string
}
type XX struct {AAname stringXXAddr string
}
type CC struct {AABBXXd DDname string
}
// 给AA结构体类型添加方法demo1
func (a *AA) demo1(){fmt.Println(a.name)
}
// 给DD结构体类型添加方法demo1
func (d *DD) demo1(){fmt.Println(d.name)
}
// 给CC结构体类型添加方法demo1
func (c *CC) demo1(){fmt.Println(c.name)
}
func main(){ins1 := new(CC)// 此时访问的是CC结构体自己字段name(就近原则)ins1.name = "Name-CC"// CC 结构体内嵌了匿名结构体AA,CC,他们的name在逻辑山处于同一层级// 要访问AA或者BB中的name 那就必须带上结构类型名ins1.AA.name = "Name-AA"// 多层级内嵌匿名结构体,访问方式也是逐层范文过去ins1.XX.AA.name = "XX(Name-AA)"// DD是CC有名结构体内嵌,或者叫组合ins1.d.name = "Name-DD"// 匿名结构体并且成员字段是唯一的,可以这样直接访问ins1.BBAddr = "addr of BB"// 组合类型的 有名内嵌那就必须带上名称ins1.d.DDAddr = "addr of DD"// 调用的是自己的方法 CC 结构体绑定的方法ins1.demo1()// 调用组合DD的demo1方法ins1.d.demo1()// 调用内嵌的匿名结构体AA的demo1方法ins1.AA.demo1()ins1.XX.demo1()
}
go run main.go
Name-CC
Name-DD
Name-AA
XX(Name-AA)

4. 多态的实现

多态 是指代码根据类型的具体实现采取不同行为的能力

在Go语言中多态的特征是通过接口 interface 来体现的

4.1 接口概述

我们将接口 看着一种双方约定的协议, 接口的实现者不用在意接口会被怎样使用,接口的调用者不用在关心接口内部的实现细节.

Go语言中接口也是一种类型,用来定义行为,也是一种抽象结构.被定义的行为不是由接口直接实现,而是通过方法由用户定义的类型实现,用户定义的类型实现了接口类型声明的一组方法,那么该用户类型就实现了该接口,同时用户定义的类型变量就可以赋给该接口类型变量,该过程会将用户定义的类型变量存入接口类型变量中,接口变量对接口定义方法的调用会执行存入的用户定义类型变量对方法的调用,此时就的调用就是一种多态

Go语言中的接口设计是 非侵入式 的, 其具体变现特征是 : 接口的定义者无需知道接口被哪些类型实现了,而接口的实现者也不需要知道实现了哪些接口,无需指明已经实现了哪些接口,只需要关注自己实现的是什么样的接口即可.编译器会自己识别哪个类型实现哪些接口

侵入式 主要体现是实现接口的类需要很明确的声明自己实现了哪个接口

4.2 声明接口

声明接口的格式如下

关键字type 和 interface
接口类型名 是自定义的,命名方式和正常的变量名相同,为了严格起见通常会在接口类型名后面追加er
函数名 和 接口类型名 的首字母大小写决定了接口和它定义的方法包外可见性
参数列表和返回值列表的定义和普通函数中的参数列表和返回值列表类似
接口中的参数列表和放回值列表中的变量名均可以忽略
接口中所有的方法都没有方法体
接口中不能定义任何变量

package main
type 接口类型名 interface {函数名1(参数列表1) 返回值列表1函数名2(参数列表2) 返回值列表2函数名3(参数列表3) 返回值列表3函数名4(参数列表4) 返回值列表4函数名5(参数列表5) 返回值列表5
}
func main(){}
package main
type Demoer interface {func1(int,string) (int ,string)func2(int,int) (int ,error)func3(s1 ,s2 string) (s3 string ,err error)func4()
}
func main(){

4.3 实现接口

接口的实现由两个基本原则

接口的方法和实现接口的类型的方法格式必须完全一致
接口中的所有方法都被实现了才能说接口被实现了

package mainimport "fmt"type Doer interface {Music()ShowTv()
}
// 实现了接口Doer
type MP4 struct {
}func (m MP4) Music() {fmt.Println("play music")
}
func (m MP4) ShowTv() {fmt.Println("play Tv")
}
func main() {var m = new(MP4)m.Music()m.ShowTv()
}

一个类型可以实现多个接口

一个接口可以被多个类型实现

package mainimport "fmt"
// Volume类型 实现CommonFunc接口
type Volume inttype BasicFunc interface {Start()Stop()
}
// 接口 CommonFunc 被两种数据类型实现
// 多种数据类型可以实现相同的接口
type CommonFunc interface {VolumeIncrease()VolumeReduce()
}
// TV类型结构体实现了CommonFunc和BasicFunc接口
type TV struct {
}func (v Volume) VolumeIncrease() {fmt.Println("音量增加")
}
func (v Volume) VolumeReduce() {fmt.Println("音量减少")
}
func (t TV) Start() {fmt.Println("开机")
}
func (t TV) Stop() {fmt.Println("关机")
}
func (t TV) VolumeIncrease() {fmt.Println("音量增加")
}
func (t TV) VolumeReduce() {fmt.Println("音量减少")
}
func main() {}

4.4 接口嵌套

Go语言中,接口与接口之间可以通过嵌套创造出新的接口

嵌套产生的新接口要被实现那么它嵌套关联的接口都被实现才行

简单讲 : X接口 是可以继承多个接口 如A接口 B接口 ,如果想实现X接口,就必须实现A,B接口中的所有方法

package main// A 接口被Demo类型事项
type A interface {FuncA()
}
// B 接口被Demo类型实现
type B interface {FuncB()
}// x 接口被Demo类型实现
type X interface {AB
}
type Demo struct {
}func (a Demo) FuncA() {}
func (b Demo) FuncB() {
}
func main() {}

4.5 类型断言的格式

类型断言的格式如下:

t := i.(T)
// t表示转换之后的变量
// i表示接口变量
// T表示转换的目标类型

接口类型可以接受任何的的数据,但是还是不知道到时什么类型,所以需要使用类型断言

package mainimport "fmt"func main(){// 定义接口类型变量 ivar i interface{}// 定义浮点类型变量fvar f float64 = 98.90// 因为i是空接口类型所以可以接受如何变量i = fx := i.(float64)fmt.Printf("x type = %T,value = %0.2f",x,x)}
go run main.go
x type = float64,value = 98.90

类型断言的如果不匹配就会报panic

这时就需要在类型断言的时候带上检测机制

基础格式如下

t,ok := i.(T)
// 和上述的类型断言格式一样
// ok 表示类型匹配是否成功的的标识,ok的类型是bool, 值为true表示成功,false表示失败 ok这个变量名是惯例写法,变量名可以自定义
package mainimport "fmt"func main() {// 定义接口类型变量 ivar i interface{}// 定义浮点类型变量fvar f float64 = 98.90// 因为i是空接口类型所以可以接受如何变量i = fx := i.(float64)fmt.Printf("x type = %T,value = %0.2f\n", x, x)y ,ok:= i.(float32)fmt.Printf("ok type = %T,value = %v\n", ok, ok)if ok{fmt.Printf("x type = %T,value = %0.2f\n", y, y)}else{fmt.Println("类型不符合")}
}
go run main.go
x type = float64,value = 98.90
ok type = bool,value = false

类型不符合

Go语言中的switch可以做的类型断言

基本格式 :

switch 任意类型变量.(type){case 类型1:处理逻辑1case 类型2:处理逻辑2...default:处理逻辑n
}
package mainimport "fmt"type Demo1 struct {data map[string]string
}
type Demo2 struct {}
func PrintType (v interface{}) {switch v.(type) {case int :fmt.Println(v,"is int")case string :fmt.Println(v,"is string")case bool :fmt.Println(v ,"is bool")case Demo1:fmt.Println(v,"is Demo1")case Demo2 :fmt.Println(v,"is Demo2")}
}
func main(){PrintType(99)PrintType("golang")PrintType(true)demo1 := Demo1{data: map[string]string{"name":"tom"}}PrintType(demo1)demo2 := Demo2{}PrintType(demo2)
}
go run main.go
99 is int
golang is string
true is bool
{map[name:tom]} is Demo1
{} is Demo2

4.6 空接口类型 interface{}

空接口是接口类型的特殊形式, 空接 口没有任何方法,因此任何类型都无须实现空接口,从实现的角度看,任何值都满足这个接口的需求

空接口也是一种类型
空间接口可以接受任何值

package mainimport "fmt"// 声明一个interface{}类型变量any
var any interface{}
func main() {// 将int型 数据99 赋值给anyany = 99fmt.Printf("any type = %T, value = %v\n",any,any)// 声明一个int型变量ivar i int// 那么是不是可以将any直接赋值给i呢?// 实际是不行的,因为any本质上是interface{}类型,而不是int型// i = any// 执行之后编译器会抛出// cannot use any (type interface {}) as type int in assignment: need type assertion// 所以我们需要用到类型断言,将interface{}类型转换成int类型赋值给ii = any.(int)fmt.Printf("i type = %T, value = %v\n",i,i)any = "golang"fmt.Printf("any type = %T, value = %v\n",any,any)any = truefmt.Printf("any type = %T, value = %v\n",any,any)}

看一个使用interface{} 的例子

package mainimport "fmt"type Dict struct {// data 作为map类型可以接受任意类型的键和值data map[interface{}]interface{}
}// 增加数据
func (d *Dict) addValue(key, value interface{}) {d.data[key] = value
}// 获取数据
func (d *Dict) GetValue(i interface{}) interface{} {return d.data[i]
}// 清空
func (d *Dict) DelAll() {d.data = make(map[interface{}]interface{})
}
func (d *Dict) Visit(callback func(k,v interface{}) bool ) {if callback == nil{return}for key,value := range d.data{if ! callback(key,value){return}}
}// 初始化
func NewDict() *Dict {d := new(Dict)d.DelAll()return d
}
func main() {d := NewDict()d.addValue("name", "tom")d.addValue("male", true)name := d.GetValue("name")fmt.Println(name)// 访问d.Visit(func(k, v interface{}) bool {fmt.Println(k,v)return true})
}
go run main.go
tom
name tom
male true

4.7 如何实现多态

我们一直说在Go语言中多态是通过接口实现的,可以按照统一的接口,调用不同的实现,此时 接口变量 就呈现不同的形态

实现多态方法1:

把接口当做 参数 在方法或者函数中传递,根据传递进来的实际接口的不同实现,体现同一个接口不同的实现

package mainimport ("fmt"
)// 定义一个接口USB,有两个方法
type USB interface {start()stop()
}// 定义Phone的类型的结构体
type Phone struct {name string
}// Phoen类型实现接口USB
func (p Phone) start() {fmt.Println(p.name, "start")
}
func (p Phone) stop() {fmt.Println(p.name, "stop")
}// 定义Pad类型的结构体
type Pad struct {name string
}// Pad实现接口USB
func (p Pad) start() {fmt.Println(p.name, "start")
}
func (p Pad) stop() {fmt.Println(p.name, "stop")
}
// 定义machine类型的结构体
type Machine struct{}
// 给Machine绑定方法Work
// 传入的参数是USB类型,凡是实现了USB的变量都可以是参数
func (m Machine) Work(u USB){u.start()u.stop()
}
func main() {var iphon Phone = Phone{"iphone"}var ipad Pad = Pad{"ipad"}// 实现接口的类型变量,可以赋值给接口变量// 被赋值的接口变量,可以像类型变量一样调用接口方法// 接口方法被具体实现的不一样,所有调用相同的方法,结果也是不一样的var usb USB// 将实例iPhone赋值给接口变量usbusb = iphonusb.start()// 将实例iPad赋值给接口变量usbusb = ipadusb.start()m := Machine{}// iPhone Iphone 实现USB接口 所以iPhone可以是变量// 因为USB接口的具体实现的不同,故同样的USB接口呈现了多态m.Work(iphon)m.Work(ipad)
}
go run main.go
iphone start
ipad start
iphone start
iphone stop
ipad start
ipad stop

实现多态方法2:

把接口当做数据类型,那么实现该接口的结构体(或者其他类型) 都是符合该接口类型

package mainimport ("fmt"
)// 定义一个接口USB,有两个方法
type USB interface {start()stop()
}// 定义Phone的类型的结构体
type Phone struct {name string
}// Phoen类型实现接口USB
func (p Phone) start() {fmt.Println(p.name, "start")
}
func (p Phone) stop() {fmt.Println(p.name, "stop")
}// 定义Pad类型的结构体
type Pad struct {name string
}// Pad实现接口USB
func (p Pad) start() {fmt.Println(p.name, "start")
}
func (p Pad) stop() {fmt.Println(p.name, "stop")
}func main() {// 定义一个map变量iArr它的键是string类型,值是USB接口类型// 那么只有实现了USB接口的数据才能符合var iArr map[string]USBiArr = make(map[string]USB)// Phone结构体类型 实现了USB ,所以可以将Phone类型的结构体可以当做值赋给变量IArriArr["iPhone X"] = Phone{"iPhonex"}// ipad结构体类型 实现了USB ,所以可以将ipad类型的结构体可以当做值赋给变量IArriArr["IPad2018"] = Pad{"Ipad2018款"}// 调用方法iArr["IPad2018"].start()iArr["IPad2018"].stop()iArr["P30"] = Phone{"华为P30"}iArr["Mate20"] = Phone{"Mate 20 X"}iArr["P30"].stop()iArr["P30"].start()
}

go run main.go

Ipad2018款 start
Ipad2018款 stop
华为P30 stop
华为P30 start

【Golang面向对象编程-第一节】相关推荐

  1. 高阶函数||编程范式: 命令式编程/声明式编程 || 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)

    编程范式: 命令式编程/声明式编程 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数) 高阶函数 filter/map/reduce filter中的回调函数有一个要求: 必须返 ...

  2. 第十章 Golang面向对象编程(上)

    结构体 看一个养猫问题 张老太养了两只猫猫:一只名字叫小白,今年3岁,白色.还有一只叫小花,今年100岁,花色.请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色.如果用户输入的小猫 ...

  3. 使用java实现面向对象编程第十章嗖嗖移动业务大厅项目_ACCP6.0使用Java实现面向对象编程-第一章.ppt...

    ACCP6.0使用Java实现面向对象编程-第一章 练习--用类图设计Dog和Penguin类 需求说明: 运用面向对象思想抽象出Dog类和Penguin类,画出对应类图 根据类图编写Dog类和Pen ...

  4. mysql菜鸟教程面向对象_第一节--面向对象编程

    第一节--面向对象编程 发布时间:2016-06-17 来源: 点击: 次 +------------------------------------------------------------- ...

  5. golang 面向对象编程

    go语言中,虽然没有明确提出面向对象的概念,但是基于已有的语法设计,我们也可以写出面向对象的代码.go语言中的面向对象是借助struct结构体实现的.值得一提的是,go语言中虽然没有class关键字来 ...

  6. 使用java实现面向对象编程第十章嗖嗖移动业务大厅项目_ACCP6.0 S2 使用Java实现面向对象编程 第一章...

    使用this调用成员方法 public void paly(int n){ health=health-n; this.print(); //this可以省略,直接调用print(): } 使用thi ...

  7. (软件工程复习核心重点)第十章面向对象设计-第一节:面向对象设计的基本概念与准则

    文章目录 一:面向对象设计概念 (1)定义 (2)设计与分析的关系 (3)分类 二:面向对象的设计准则 (1)模块化 (2)抽象 (3)信息隐藏 (4)低耦合 A:交互耦合 B:继承耦合 (5)高内聚 ...

  8. Java面向对象编程 第一章 面向对象开发方法概述

    一.软件开发经历的生命周期: ①软件分析 ②软件设计 ③软件编码 ④ 软件测试 ⑤ 软件部署 ⑥软件维护 二.为了提高软件开发效率,降低软件开发成本,一个优良的软件系统应该具备以下特点: ① 可重用性 ...

  9. Android人生整理第二章:Java编程第一节-对象导论

    抽象过程:建立解空间(问题建模) 和问题空间 (问题存在) 关联 万物皆为对象 程序是对象的集合,通过发送消息来告知彼此要做的 每个对象都有自己的由其他对象构成的存储 所有对象都有类型 某一特定类型的 ...

最新文章

  1. 修改github用户名
  2. java转换音频采样率_转换音频采样率
  3. ARM版本的IAR下载和安装
  4. datetimepicker控件怎么改变hover颜色_VBA入门课程,ActiveX控件系列知识,复合框的属性与常见VBA代码...
  5. 网络编程释疑之:TCP的TIME_WAIT状态在服务器开发中的影响?
  6. html云雾效果,PS中怎么做像这样的云雾效果?(有图)?
  7. 程序员从幼稚到成熟会经历哪些变化?你都知道吗?
  8. 程序猿过年相亲:你总会遇到一个女孩,她不向你要钱,房子和车....
  9. 3行!仅3行代码就能抓取B站数据
  10. 计算机科学申请文书,美国留学:看牛人怎么写申请计算机CS专业的文书
  11. python生成热度图_Python数据可视化 热力图
  12. Redisbook学习笔记(3)数据类型之列表
  13. 对《Java核心技术卷一》读者的一些建议
  14. FeHelper ( 浏览器插件 )
  15. MATLAB数值计算函数汇总
  16. 驾考——科一,三笔记
  17. Google搜索的基本语法
  18. EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.
  19. 有一个已经排好序的数组,要求输入一个数后,按原来排序规律将它插入数组中。
  20. win10+GPU+MATLAB+MatConvNet配置

热门文章

  1. mysql创建table w3c_MySQL 管理
  2. 解决centos7虚拟机使用git 下载代码出现网络不可达的问题
  3. 说python好的文章大多在吹牛
  4. 人事管理信息系统mysql代码_人事管理系统——数据库操作类
  5. 如何使用强化学习进行量化投资?
  6. 感恩前行 秀兰集团成立22周年庆典举办
  7. 机器学习常用的距离度量方法
  8. 【C#笔记】SaveFileDialog的简单用法
  9. 马来西亚政府于15日下午在吉隆坡举行发布会
  10. Linux so剖析