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 标签名
相关文章
|
4天前
|
云安全 监控 安全
|
1天前
|
存储 机器学习/深度学习 人工智能
打破硬件壁垒!煎饺App:强悍AI语音工具,为何是豆包AI手机平替?
直接上干货!3000 字以上长文,细节拉满,把核心功能、使用技巧和实测结论全给大家摆明白,读完你就知道这款 “安卓机通用 AI 语音工具"——煎饺App它为何能打破硬件壁垒?它接下来,咱们就深度拆解煎饺 App—— 先给大家扒清楚它的使用逻辑,附上“操作演示”和“🚀快速上手不踩坑 : 4 条核心操作干货(必看)”,跟着走零基础也能快速上手;后续再用真实实测数据,正面硬刚煎饺 App的语音助手口令效果——创建京东「牛奶自动下单神器」口令 ,从修改口令、识别准确率到场景实用性,逐一测试不掺水,最后,再和豆包 AI 手机语音助手的普通版——豆包App对比测试下,简单地谈谈煎饺App的能力边界在哪?
|
9天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1123 6
|
11天前
|
机器学习/深度学习 人工智能 数据可视化
1秒生图!6B参数如何“以小博大”生成超真实图像?
Z-Image是6B参数开源图像生成模型,仅需16GB显存即可生成媲美百亿级模型的超真实图像,支持中英双语文本渲染与智能编辑,登顶Hugging Face趋势榜,首日下载破50万。
723 42
|
15天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
1166 41
|
15天前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
930 77
大厂CIO独家分享:AI如何重塑开发者未来十年
|
3天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
|
1天前
|
人工智能 JSON 前端开发
为什么你的API文档总是被吐槽?用这份"契约指令"终结前后端战争
本文针对前后端协作中"文档过时、不准确"的痛点,提供了一套实战验证的AI指令。通过强制结构化输入和自检机制,让AI自动生成包含完整参数、JSON示例和多语言代码的标准API契约文档,彻底解决接口沟通难题。
171 112
|
10天前
|
存储 自然语言处理 测试技术
一行代码,让 Elasticsearch 集群瞬间雪崩——5000W 数据压测下的性能避坑全攻略
本文深入剖析 Elasticsearch 中模糊查询的三大陷阱及性能优化方案。通过5000 万级数据量下做了高压测试,用真实数据复刻事故现场,助力开发者规避“查询雪崩”,为您的业务保驾护航。
557 32

热门文章

最新文章