go基本语法

跟Java比较学习。

hello word

示例代码

test1.go文件:
// 包路径
package main

// 导入模块,下面两种都行
import (
    "fmt"
)
import "log"

//  main方法
func main() {
    log.Print("hello word !!!")
    fmt.Print("hello word 222")
}

运行命令

go run .\test1.go

打包二进制

> go build .\test1.go

./test1.exe

变量可见性

首字母大写就是public

首字母小写就是private

{不能单独一行

在Java和C中都可以,go中就不行

正确的应该这样:

行结束不需要分号;

加上后IDE会自动给删除

如果你就是要将两行代码放在一行,则需要在结尾加上;分号,但IDEA会在保存的时候自动给你拆分为两行。

字符串

字符串连接+

格式化

// 格式化String.format
value := fmt.Sprintf("%s - %s", ">>", "<<")
// 打印到console上
fmt.Print(value)

// 合并:格式化并打印出
fmt.Printf("%s - %s\n", ">>", "<<")

变量

变量申明和赋值

// 只声明一个变量i
var i int
// 给i变量赋值2
i = 2
// 创建变量并赋值3
ii := 3
// 声明常量
const pi float64 = 3.14

var bo bool = false
bo1 := false
var f1 float32 = 1.1
var f2 = 1.2
f3 := 1.3

普通变量类型

uint8 unsiged int 8位

int8 有符号8位int

int16,int32,int64 类似,没有long

float32、float64 容易理解,没有double

这两个不清楚:

complex64 32 位实数和虚数

complex128 64 位实数和虚数

不一样的:

uintptr 无符号整型,用于存放一个指针

rune 类似 int32

byte 类似 uint8  0到255

变量作用域

全局变量和局部变量可以名称一致,但使用时会优先使用局部变量。

数组

一维数组

var strs = [3]string{"111", "222", "333"}
// 初始化数组中 {} 中的元素个数不能大于 [] 中的数字。 多出就会报错
var strs = [3]string{"111", "222", "333","444"}
// 只初始化了前两个元素
var strs = [3]string{"111", "222"}
// 数组长度根据后边初始化数据的个数来确定为2
var strs = [...]string{"111", "222"}
// 初始化指定元素下表元素的数据
var strs = [...]string{1: "111", 4: "222"}
// 数组的长度
var length int = len(strs)
fmt.Println("数组长度:", length)
for i := 0; i < length; i++ {
    // 访问和给数组赋值
    fmt.Println(len(strs[i]))
    strs[i] = "ab"
}

二维数组 

// 定义二位数组,并初始化
var rows = [][]int{
    {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
}
fmt.Println(rows)

// 二位数组一行一行添加
// [3][3]int{} 错误,行列取悦于append了多少次
var rows1 = [][]int{}
var row1 = []int{1, 2, 3}
var row2 = []int{4, 5, 6}
// 各行可以一样,也可不一样长
var row3 = []int{7, 8, 9, 10}
rows1 = append(rows1, row1)
rows1 = append(rows1, row2)
rows1 = append(rows1, row3)
fmt.Println(rows1)
fmt.Println("row count:", len(rows1))
fmt.Println("col count:", len(row1))
fmt.Println("row1 :", rows[0])
fmt.Println("row2 :", rows[1])
// 不允许访问列 rows[][1]   syntax error: unexpected ], expected operand
// fmt.Println("col1 :", rows[][1])
fmt.Println("cell[1][1] :", rows[1][1])

// 遍历二维数组
for i := 0; i < len(rows1); i++ {
    for j := 0; j < len(rows1[i]); j++ {
        fmt.Println("cell[", i, "][", j, "] : ", rows1[i][j])
    }
}

方法参数传数组和传指针

// 包路径
package main

import "fmt"

//  main方法
func main() {
    
    // 定义二位数组,并初始化
    var rows = [][]int{
        {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
    }
    fmt.Println(rows)
    addRow(rows)
    fmt.Println(rows)
    
    // 传递二维数组的指针 &rows
    addRow1(&rows)
    fmt.Println(rows)
    
    // 调用固定元素数组参数,必须是固定元素个数数组
    // 数量不一致直接报错
    row1 := [5]int{1, 2, 3, 4, 5}
    printRow(row1)
    
    // 将二维数组的第一行当做一维数组也不行
    // printRow(rows[0])
}

// 数组是值类型,这么传实际传的是值而非引用
func addRow(rows [][]int) {
    row := []int{11, 22}
    rows = append(rows, row)
}

// 接受一个二位数组的指针,就是地址
func addRow1(rows *[][]int) {
    row := []int{11, 22}
    *rows = append(*rows, row)
}

//  必须这么调用:row1 := [5]int{1, 2, 3, 4, 5};    printRow(row1)
func printRow(row [5]int) {
    fmt.Println(row)
}

指针数组

// 定义指向数组的指针数组
ptr := []*int{&rows[0], &rows[1], &rows[2]}

指向指针的指针

var pptr **int
已经很熟悉了,不用再说了。

 结构体

基本语法

// 包路径
package main

import "fmt"

// Book 全局可以使用
type Book struct {
    title string
    auth  string
}

//  main方法
func main() {
    // 定义结构体,只能在方法里边用
    /*type Book struct {
        title string
        auth  string
    }*/
    
    var book1 Book
    book1 = Book{"title1", "auth2"}
    book1 = Book{title: "title2"}
    // book2 获取book1的值,最后那个也添加了个逗号,恶心不
    book2 := Book{
        title: book1.title,
        auth:  book1.auth,
    }
    book1.auth = "1000"
    
    // 传值:不会修改值
    setAuth200(book2)
    
    // 传地址:会修改值
    setAuth200Point(&book2)
    
    var book3 Book
    // 没有book3 == nil 和 book3 == null这么一说
    // 是空对象相当于java中:book3 = new Book(); 不给里边赋值,所以直接访问不报错
    fmt.Println(book3)
    book3.auth = "2000"
}

// 真NM耐造,book为null 不会报错
func setAuth200(book Book) {
    book.auth = "2000"
}

func setAuth200Point(bookPtr *Book) {
    (*bookPtr).auth = "2000"
}

 继承和匿名字段

type Person struct {
    name string
    sex  string
    age  int
}

func (p *Person) say() {
    fmt.Println("person fun11")
}

type Student struct {
    // 将Person中的属性继承过来 s1.sex
    Person
    // 创建person属性 s1.person.sex
    person Person
    id     int
    addr   string
    // 如果出现重名情况
    age int
    // 匿名字段
    string
}

// 继承和匿名字段
func main() {
    fmt.Println("main ...")

    s1 := Student{Person{"5lmh", "man", 20}, Person{"5lmh", "man", 20}, 1, "bj", 20, "匿名字段"}
    fmt.Println(s1)
    // 获取person属性的sex值
    fmt.Println(s1.person.sex)
    // 获取继承过来的person属性sex
    fmt.Println(s1.sex)
    fmt.Println(s1.Person.sex)

    // 如果父子类中的属性重复
    // 给父类Person中赋值
    s1.Person.age = 100
    // 给子类属性age赋值
    s1.age = 200
    fmt.Println(s1)

    // 继承还可以继承方法
    s1.say()

    fmt.Println("success ...")
}

切片Slice

类似java的ArrayList 

var arr = []int{1, 2, 3, 4, 5}
fmt.Println(arr)

// 切片类似:数组的 substring,前后是包含关系
sp := arr[0:]
fmt.Println(sp)
fmt.Println(len(sp))
fmt.Println(cap(sp))

// 使用mark创建
var number = make([]int, 3, 5)
fmt.Println(number, len(number), cap(number))
// 在3个元素后边添加
number = append(number, 5)
// out: [0 0 0 5] 4 5
fmt.Println(number, len(number), cap(number))
number = append(number, 6)
number = append(number, 7)
number = append(number, 8)
// 长度超过容量后会自动扩容,二倍扩容
number = append(number, 9)
number = append(number, 10)
//out:[0 0 0 5 6 7 8 9 10] 9 10
fmt.Println(number, len(number), cap(number))

var number1 = make([]int, len(number)*2, cap(number)*2)
copy(number1, number)
// out:[0 0 0 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0] 18 20
// len内的数据会默认给0
fmt.Println(number1, len(number1), cap(number1))

// 将里边的数据全部清理为0
clear(number1)
// out:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 18 20
fmt.Println(number1, len(number1), cap(number1))

语言范围Rang

 rang 类似 java中的 迭代器 foreach

数组

// 遍历数组,index是下标
intArr := []int{1, 2, 3, 4, 5}
for index := range intArr {
    fmt.Print(index, "=", intArr[index], " ")
}
fmt.Println("")
// 可以直接将value遍历出来
for index, value := range intArr {
    fmt.Print(index, "=", value, " ")
}
fmt.Println("")
// 如果不需要index则可以用_替代,否则由会给你报错,这个变量没用
for _, value := range intArr {
    fmt.Print(value, " ")
}

 Map

// map的遍历
fmt.Println("")
map1 := make(map[int]string, 3)
fmt.Println(map1)
map1[10] = "aa"
map1[11] = "bb"
fmt.Println(map1)
// 遍历map,当前key和value如果不用,可以用_替代
for key, value := range map1 {
    fmt.Println(key, ":", value)
}
// 如果只有一个同样,遍历的是key,类似数组的index
for key := range map1 {
    fmt.Println(key)
}

切片 

fmt.Println("")
// 切片也可以类似
spArr := make([]int, 2, 50)
copy(spArr, intArr[3:])
// out:[4 5]
fmt.Println(spArr)
for index := range spArr {
    fmt.Print(index, "=", intArr[index], " ")
}

channel 

// channel 看样子类似java中的MQ,但不用那么复杂的实现机制
// chan int : 首先这个是一个通道channel, 然后是一个装int的channel
// 类似:LinkedQuery<Integer>
ch := make(chan int, 10)
ch <- 11
ch <- 12
ch <- 1000

for val := range ch {
    fmt.Print(val, " ")
    // 一边遍历,一边可以添加数据,比ArrayList的强多了
    // 但这么搞就死循环了,逻辑上注意
    // ch <- 1000
}
// 最后需要关闭
close(ch)

Map集合 

// 创建 <int,string> 初始容量为2
mapCap := 2
map1 := make(map[int]string, mapCap)
fmt.Println(map1)

// 添加元素,可相同会覆盖
map1[11] = "bb"
fmt.Println(map1)
map1[11] = "bbb"
map1[22] = "ccc"
map1[33] = "ddd"
fmt.Println(map1)

// 根据Key删除元素
fmt.Println(len(map1))
delete(map1, 22)
fmt.Println(map1)
fmt.Println(len(map1))

// 获取元素,如果没有则为空
fmt.Println("key:", 11, ",value:", map1[11])
fmt.Println("key:", 66, ",value:", map1[66])
// 如果有值则 value就是值,hasBollen为true,如果没有值 hasBollen = false
value, hasBollen := map1[66]
if hasBollen {
    fmt.Println("数据存在,value:", value)
} else {
    fmt.Println("数据不存在,key:", 66)
}

// 遍历map
fmt.Println(map1)
for key, value := range map1 {
    fmt.Println("key:", key, ",value:", value)
}

方法

匿名方法 

func(i int, wg *sync.WaitGroup)为形参
(i, &wg) 为实际参数
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
    wg.Add(1)
    go func(i int, wg *sync.WaitGroup) {
       fmt.Println(i)
       time.Sleep(20 * time.Microsecond)
       wg.Done()
    }(i, &wg)
}
wg.Wait()

接口Interface

不同点:

1. struct 实现 interface,并没有明显的实现写法,各写各的

2. struct 可以实现部分interface的方法,而不必要全部实现。直接用没问题,用interface进行引用就报错:

 

// 包路径
package main

import "fmt"

// 接口有两个方法
type Animal interface {
    call()
    getName() string
}

// 创建类Market,有一个name熟悉
type Market struct {
    name string
}

/**
  实现方法:
  1. (m Market): 标识 这个是Market类的方法
  2. call() 接口的方法
*/
func (m Market) call() {
    fmt.Println("market call,", "name:", m.name)
}

func (m Market) getName() string {
    return m.name
}

type Tiger struct {
    name string
}

func (t Tiger) call() {
    fmt.Println("tiger call,", "name:", t.name)
}

func (t Tiger) getName() string {
    return t.name
}

func animalCall(a Animal) {
    a.call()
}

// 空接口,可以接受任何类型的对象,并根据类型判断
func print(v interface{}) {
    switch t := v.(type) {
    case int:
        fmt.Println("integer", t)
    case string:
        fmt.Println("string", t)
    }
}

//  main方法
func main() {
    
    // 接口 interface
    m1 := Market{name: "m111"}
    fmt.Println(m1.getName())
    m1.call()
    
    m2 := new(Market)
    m2.name = "m222"
    m2.call()
    
    t1 := Tiger{name: "t1111"}
    fmt.Println(t1.getName())
    t1.call()
    
    // 根据传值的不同
    animalCall(m1)
    animalCall(t1)
    
    // 定义一个接口,然后复制类对象,按照接口调用就可以
    var a1 Animal
    a1 = m1
    a1.call()
    
    // 将m1转换为 Market类型
    m11 := a1.(Market)
    fmt.Println(m11.name)
    
    // 空接口接受人任何对象
    print(11)
    print("str11")
    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/977880.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux内核,slub分配流程

我们根据上面的流程图&#xff0c;依次看下slub是如何分配的 首先从kmem_cache_cpu中分配&#xff0c;如果没有则从kmem_cache_cpu的partial链表分配&#xff0c;如果还没有则从kmem_cache_node中分配&#xff0c;如果kmem_cache_node中也没有&#xff0c;则需要向伙伴系统申请…

冯诺依曼体系结构 ──── linux第8课

目录 冯诺依曼体系结构 关于冯诺依曼&#xff0c;必须强调几点&#xff1a; 冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系 输入单元&#xff1a;包括键盘, 鼠标&#xff0c;网卡,扫…

国标28181协议在智联视频超融合平台中的接入方法

一. 国标28181介绍 国标 28181 协议全称是《安全防范视频监控联网系统信息传输、交换、控制技术要求》&#xff0c;是国内视频行业最重要的国家标准&#xff0c;目前有三个版本&#xff1a; 2011 年&#xff1a;推出 GB/T 28181-2011 版本&#xff0c;为安防行业的前端设备、平…

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(四)

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;四&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响应&…

音乐游戏Dance Dance Revolution(DDR)模拟器

文章目录 &#xff08;一&#xff09;Dance Dance Revolution&#xff08;1.1&#xff09;基本情况&#xff08;1.2&#xff09;机体 &#xff08;二&#xff09;模拟器&#xff08;2.1&#xff09;主程序&#xff08;2.2&#xff09;模拟器主题 &#xff08;三&#xff09;曲谱…

货车一键启动无钥匙进入手机远程启动的正确使用方法

一、移动管家货车无钥匙进入系统的使用方法 基本原理&#xff1a;无钥匙进入系统通常采用RFID无线射频技术和车辆身份识别码识别系统。车钥匙需要随身携带&#xff0c;当车钥匙靠近货车时&#xff0c;它会自动与货车的解码器匹配。开门操作&#xff1a;当靠近货车后&#xff0…

vscode如何使用鼠标滚轮调整字体大小

1.打开设置 2.搜索Font Ligatures 3.编辑配置文件 4.修改代码并保存 修改前 修改后 在最后一行添加&#xff1a;“editor.mouseWheelZoom”: true 记得在上一行最后&#xff0c;加上英文版的“,”逗号 5.配置成功&#xff0c;再次按Ctrl鼠标滚轮便可以缩放了。

视频裂变加群推广分享引流源码

源码介绍 视频裂变加群推广分享引流源码 最近网上很火&#xff0c;很多人都在用&#xff0c;适合引流裂变推广 测试环境&#xff1a;PHP7.4(PHP版本不限制) 第一次访问送五次观看次数&#xff0c;用户达到观看次数后需要分享给好友或者群,好友必须点击推广链接后才会增加观看次…

redis小记

redis小记 下载redis sudo apt-get install redis-server redis基本命令 ubuntu16下的redis没有protected-mode属性&#xff0c;就算sudo启动&#xff0c;也不能往/var/spool/cron/crontabs写计划任务&#xff0c;感觉很安全 #连接到redis redis-cli -h 127.0.0.1 -p 6379 …

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决

IDEA关闭SpringBoot程序后仍然占用端口的排查与解决 问题描述 在使用 IntelliJ IDEA 开发 Spring Boot 应用时&#xff0c;有时即使关闭了应用&#xff0c;程序仍然占用端口&#xff08;例如&#xff1a;4001 端口&#xff09;。这会导致重新启动应用时出现端口被占用的错误&a…

Vue04

自定义指令 directives是Vue的一个配置项 这里写自定义指令 自定义指令被调用的时机 指令与元素成功绑定时 指令所在的模板被重新解析时 函数式 <span v-big"n"></span> directives:{ big(element,binding){ element.innerText bingin…

岳阳市美术馆预约平台(小程序论文源码调试讲解)

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

Linux 基本开发工具的使用(yum、vim、gcc、g++、gdb、make/makefile)

文章目录 Linux 软件包管理器 - yum理解什么是软件包和yum如何查看/查找软件包如何安装软件如何实现本地机器和云服务器之间的文件互传如何卸载软件 Linux 编辑器 - vim 的使用vim 的基本概念vim 的基本操作vim 命令模式各命令汇总vim 底行模式各命令汇总vim 的简单配置 Linux …

4部署kibana:5601

kibana 是一个基于浏览器页面的Elasticsearch前端展示工具&#xff0c;, 是一个开源和免费的工具 Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面, 可以帮你汇总、分析和搜索重要数据日志 1.安装-所有的es节点 # tar xf kibana-6.4.1-linux-x86_64.t…

1.介绍一下TCP/IP模型和OSI模型的区别【中高频】

OSI模型 将 这个协议 划分为7个不同的层级&#xff0c;分别为物理层、数据链路层、网络层、传输层、会话层、表示层和应用层&#xff0c;而TCP/IP模型只有4个层级&#xff0c;分别为网络接口层、网络层、传输层和应用层&#xff0c;其中应用层在用户态&#xff0c;传输层及以下…

【反爬】拦截comBusiness.js disable-devtool.js

一、现象 无法使用ctrls保存网页&#xff0c;但是可以在设置菜单中可以保存&#xff1b;无法使用F12和ctrlshifti打开开发者窗口&#xff0c;但是可以在设置菜单中打开&#xff1b;打开开发者窗口后网站快速关闭&#xff0c;说明被检测到了&#xff1b; 二、涉及js 打开设置菜…

【11】子网

区块链子网概述 什么是子网&#xff1f; 子网是在较大网络上下文中运行的较小网络&#xff0c;因此由对应的“主网”&#xff0c;主网即包含多个子网的较大网络或具有隶属关系的上一级网络。子网允许在主网中进行一些独立的事务或控制网络参数。 对于互联网而言&#xff0c;…

爬虫基础入门之爬取豆瓣电影Top250-Re正则的使用

网址:豆瓣电影 Top 250 本案例所需要的模块 requests (用于发送HTTP请求)re (用于字符串匹配和操作) 确定需要爬取的数据 &#xff1a; 电影的名称电影的年份电影的评分电影评论人数 一. 发送请求 模拟浏览器向服务器发送请求 准备工作 -分析页面: F12 or 右击点击检查 查看…

论文笔记(七十二)Reward Centering(五)

Reward Centering&#xff08;五&#xff09; 文章概括摘要附录B 理论细节C 实验细节D 相关方法的联系 文章概括 引用&#xff1a; article{naik2024reward,title{Reward Centering},author{Naik, Abhishek and Wan, Yi and Tomar, Manan and Sutton, Richard S},journal{arX…

Flash-03

1-问题&#xff1a;Flash软件画两个图形&#xff0c;若有部分重合则变为一个整体 解决方法1&#xff1a;两个图形分属于不同的图层 解决方法2&#xff1a;将每个图形都转化为【元件】 问题2&#xff1a;元件是什么&#xff1f; 在 Adobe Flash&#xff08;现在称为 Adobe Anim…