106【GoLand-基础2】(四)

简介: 106【GoLand-基础2】
  1. 接口和类型(结构体)的关系
  1. 一类型可以实现多个接口
  2. 多个类型可以实现同一个接口 (多态)
1..一个类型可以实现多个接口: 有一个player接口可以播放音乐,有一个vido接口可以播放视频,一个Phome可以同时实现这俩接口,边听儿歌变看视频。
******************************************************
package main
import (
  "fmt"
)
type Music interface {
  audio()
}
type Video interface {
  TV()
}
type Phone struct {
  name string
}
func (p Phone) audio() {
  fmt.Printf("%v,正在听音乐...", p.name)
}
func (p Phone) TV() {
  fmt.Printf("%v,正在看视频...", p.name)
}
func main() {
  var music Music
  var tv Video
  phone := Phone{
    name: "iqoo",
  }
  music = phone //实体类赋值接口
  tv = phone
  music.audio()
  tv.TV()
}
******************************************************
2.多个类型可以实现同一个接口 (多态)
package main
import (
  "fmt"
)
type Music interface {
  audio()
}
type Phone struct {
  name string
}
func (p Phone) audio() {
  fmt.Printf("%v,正在听音乐...", p.name)
}
type Computer struct {
  name string
}
func (c Computer) audio() {
  fmt.Printf("%v,正在听音乐...", c.name)
}
func main() {
  var music Music
  phone := Phone{
    name: "iqoo",
  }
  music = phone //实体类赋值接口
  music.audio()
  computer := Computer{
    name: "HP",
  }
  music = computer //实体类赋值接口
  music.audio()
}
  1. 接口嵌套

接口可以通过嵌套,创建新的接口。列如: 飞鱼,既可以飞,又可以游泳。我们创建一个飞Fly接口,创建一个游泳接口,飞鱼接口有这两个接口组成

package main
import "fmt"
type Fly interface {
  flying()
}
type Swim interface {
  swimming()
}
type FlyFish interface {
  Fly
  Swim
}
type Fish struct {
  name string
}
func (f Fish) flying() {  //实现飞的方法
  fmt.Printf("%v,正在飞.....", f.name)
}
func (f Fish) swimming() { //实现游泳的方法
  fmt.Printf("%v,正在游泳.....", f.name)
}
func main() {
  var fish FlyFish //定义接口
  f := Fish{
    name: "飞鱼",
  }
  fish = f  //对接口进行赋值
  fish.swimming()
  fish.flying()
}
  1. 通过接口实现OCP设计原则

而面向对象的可复用设计的第一块基石,便是所谓的 开-闭(Open-Closed Principle) 原则。虽然,go不是面向对象的语言,但也是可以模拟实现这个原则。对扩展是开放的,对修改是关闭的

在本次测试中: 我们初设两个实现方法cat和dog,猫和狗此时并没有率属于人类结构体下,我们可以实现对人类结构体进行扩展的操作。

package main
type Pet interface {
  eat()
  sleep()
}
type Dog struct {
}
type Cat struct {
}
//Dog实现接口
func (d Dog) eat() {
  println("Dog在eat....")
}
func (d Dog) sleep() {
  println("Dog在sleep....")
}
// Cat实现接口
func (c Cat) eat() {
  println("Cat在eat....")
}
func (c Cat) sleep() {
  println("Cat在sleep....")
}
type Person struct {
}
// pet既可以传递Dog也可以传递Cat
func (p Person) care(pet Pet) {  //接口接受
  pet.eat()
  pet.sleep()
}
func main() {
  dog := Dog{}
  cat := Cat{}
  person := Person{}
  person.care(dog)   //我们这里传递实体
  person.care(cat)  //我们这里传递实体
}
  1. 模拟OOP的属性和方法

Go没有面向对象的概念,也没有封装的概念。但是可以通过结构体 struct函数绑定来实现OOP的属性和方法特性。接收者receiver方法。通俗的讲: 就是属性和方法分开定义

列如: 想要定义一个Person类,有name和age属性,有 eat/sleep/work方法

package main
import "fmt"
type Person struct {
  name string
  age  int
}
func (p Person) play() {
  fmt.Printf("%v\n正在玩游戏...", p.name)
}
func (p Person) Listener() {
  fmt.Printf("%v\n正在听歌...", p.name)
}
func main() {
  person := Person{
    name: "吉士先生",
    age:  20,
  }
  person.play()
  person.Listener()
}

7.Go继承

本质上没有oop的概念,也没有继承的概念,但是可以通过 结构体嵌套 实现这个特性。

内嵌结构体的话,我们可以省略调用内嵌结构体的变量名

package main
import "fmt"
type Animal struct {
  name string
}
func (a Animal) eat() {
  println("正在吃...")
}
func (a Animal) sleep() {
  fmt.Printf("%v正在睡...", a.name)
}
type Cat struct {
  //animal Animal //内嵌可以理解成继承的关系
  Animal  //内嵌结构体我们可以直接省略掉变量名
}
func main() {
  cat := Cat{
    Animal{  //因为上面省略了,所以我们这里也可以省略变量名  animal:=Animal{}
      name: "花花",
    },
  }
  cat.sleep() // 直接调用,因为省掉变量名了
  //cat.animal.sleep()  //这里是不省略
}
  1. 构造函数

Go没有构造函数的概念,可以使用函数来模拟构造函数的功能

利用函数来模拟构造函数...

package main
import "fmt"
type Person struct {
  name string
  age  int
}
func NewPerson(name string, age int) (*Person, error) {
  if name == "" {
    return nil, fmt.Errorf("name 不能为空")
  }
  if age < 0 {
    return nil, fmt.Errorf("age 不能为负")
  }
  return &Person{
    name: name,
    age:  age,
  }, nil
}
func main() {
  person, err := NewPerson("李明", 20)
  fmt.Printf("%v", *person)
  fmt.Printf("%v", err)
}

7.输出函数

格式化输出

%v 万能变量  %d 十进制整数 %f 浮点型 %s 字符串 %c 字符 %T 数据类型
%#v 详细万能变量  %p 指针 %t 布尔 &取地址
fmt.printf("%v",identify)  ->格式化输出

换行输出

fmt.println()

不换行输出

fmt.print()

8.关系运算符和逻辑运算符和位运算符

  1. 关系运算符
1. ++和-- 不能放到表达式里面。只能先输出再调用。
++ -- + - * / += -= /=
> = < >= <=

2.逻辑运算符

&&  一个为假全为假
||  一个为真全为真
!  真为假 假为真

3.位运算符

& : 一个为假全为假
| : 一个为真全为真
^ : 不同为0,相同为1
<<  左移  : 左边非0的保留,右边添加0
>> 右移   : 右边非0也不保留,

9.Go语言的流程控制

1.顺序

从上->倒下
  1. 条件判断
1. if语句判断执行流程
if 布尔表达式 {
}else if 布尔表达式{
} else{
}
(1).在Go语言中,表达式不需要用括号括起来。
(2).左括号{}必须存在if或else的同一行
(3).在if之后,条件语句之前,可以添加变量初始化语句,使用分割进行分割。
eg:
if idenfied:=value;idenfied>20{}
----------------------
2. switch进行条件判断默认是不穿透的。
3. Go语言switch语句,可以同时匹配多个条件,中间用逗号分割,有其中一个匹配成功即可。
switch idenfied{
case 1,2,3,4,5: println("工作日")
default: println("休息日")
}
4. Go语言的switch语句的case可以放置:判断表达式
5. fallthroug 设置穿透,Go语言默认是不穿透的。break打断穿透。0
  1. 循环

GO语言中只有for没有while{},do while{}

1. for 初始条件;条件表达式;结束语句{
 循环体
}
2. for表达式不需要加括号
3. 初始条件我们可以在外部定义。
4. 永真循环,就是我们的条件都不要。类似于while循环
for{} 或者 for ; ;{}
-----------
1. for index,value:=range 数组/字符串/map/chan{函数体}
2. 如果不需要的话,可以用匿名变量进行占位置
for i,v:=range identify{
}

10.Break与Continue与goto与标签💥

  1. Break
1. 单独在select中使用break和不使用break没有啥区别
2. 单独在表达式switch语句,并且没有fallthrough,使用break和不适用没有啥区别
3. 单独在表达式switch语句中,并且有fallthrough,使用break能够终止穿透
4. 带标签的break,可以跳出多层select/switch作用域,让break更加零花,不需要使用控制变量一层层的跳出循环,没有带break的只能跳出当前语句块。
(1).可以终止for循环
(2).可以打破switch的fallthrough穿透
(3).可以跳出标签
package main
func main() {
  /**
  * 正常情况下,我们需要俩个break才能跳出双层循环。如果我们添加了标签就会直接跳转到外面,无需俩break
   */
MY_LABEL:  //标签
  for i := 0; i < 5; i++ {
    for j := 0; j < 5; j++ {
      if i == 2 {
        break MY_LABEL  //标签
      }
      println("你好")
    }
    println(i)
  }
  println("end....")
}
  1. continue

continue只能在循环中,在go中只能用for循环中,它可以终止本次循环,进行下一次循环。在continue语句后添加标签时,表示开始标签对应的循环。

1. 在for循环中使用continue,会跳过此次循环,但不会终止后面的循环

3.goto

goto语句通过标签进行代码间的无条件跳转,goto语句可以在快速跳转循环、避免重复退出上有一定的帮助.Go语言中使用goto语句能够简化一些代码的实现过程。比如双层嵌套的for循环要退出时。

1. goto 标签名 与 break 标签名的区别
(1).break的标签名只能放在for循环上面,不能放在其他位置,goto的标签名可以随便放,不必只放在for寻黄傻瓜
(2).break的标签必须先定义再使用,goto可以先定义再使用也可以先使用再定义

goto 进行跳转

package main
func main() {
  for i := 0; i < 5; i++ {
    for j := 0; j < 5; j++ {
      if i == 2 {
        goto first_range //标签的使用
      }
      println("你好")
    }
    println(i)
  }
  println("end....") //这里是不会打印的,直接跳转
first_range: //标签的定义
  println("end2....")
}

  1. 标签的定义和使用
  1. break调用标签的话,必须使用在for循环之上。必须先定义后使用
  2. goto调用标签的话,可以先使用再调用,不必须在for循环下。位置随便放
  3. goto标签,如果goto跳转之后会直接跳转到标签所在的位置
  4. break标签,会退出循环。
1. 定义
    标签名: 
2. 使用
    break 标签名
    goto 标签名
相关文章
|
2天前
|
Go
GoLand创建项目过程
GoLand创建项目过程
16 0
|
6月前
|
Cloud Native 测试技术 Go
你不知道的goland技巧
你不知道的goland技巧
|
6月前
|
IDE Go 开发工具
Go开发IDE全览:GoLand vs VSCode全面解析
Go开发IDE全览:GoLand vs VSCode全面解析
221 0
|
6月前
|
C++
03 C++ - CLion创建程序
03 C++ - CLion创建程序
59 0
|
8月前
|
Go 索引 容器
106【GoLand-基础2】(二)
106【GoLand-基础2】
24 0
|
8月前
|
Go
106【GoLand-基础2】(三)
106【GoLand-基础2】
21 0
|
8月前
|
测试技术 编译器 Go
106【GoLand-基础2】(一)
106【GoLand-基础2】
40 0
|
11月前
|
缓存 Java 程序员
2023年最新无脑安装 Go lang 环境配置并编写、运行、打包第一个 Golang 程序详细步骤,附带图文教程
GO语言也称为Golang,由谷歌出品,随着云计算的发展而不断壮大,近年来,使用GO语言的程序员越来越多,GO程序员一般被称为GOpher。由于博主硬盘空间较为充足,不考虑移动软件安装目录,需要者请自行寻找方法,本文为无脑操作。
318 0
2023年最新无脑安装 Go lang 环境配置并编写、运行、打包第一个 Golang 程序详细步骤,附带图文教程
|
移动开发 前端开发 小程序
为了偷懒,我用google/zx一键自动打包编译了前后端项目并发布到指定环境
由于正在负责的一个项目,就说前端涉及到PC端、公众号端、APP端的H5、小程序端、可视化大屏端,而PC和APP又通过qiankun引入了微前端的理念。整体一圈下来可能光前端编译打包就要build差不多二十次。而有时候经常性的bug改动,这个时候便只需要进行测试后需要进行小范围的测试。
179 0
|
API iOS开发 开发者
Xcode自动打包和上传蒲公英平台脚本(用python实现)
工作中,特别是所做项目进入测试阶段,肯定会经常打 Ad-hoc 包给测试人员进行测试,但是我们肯定不想每次进行打包的时候都要进行一些工程的设置修改,以及一系列的 next 按钮点击操作,现在就让这些操作都交给脚本化吧!
317 0