Golang学习Day3

news2024/9/28 1:24:23
😋 大家好,我是YAy_17,是一枚爱好网安的小白。
本人水平有限,欢迎各位师傅指点,欢迎关注 😁,一起学习 💗 ,一起进步 ⭐ 。
⭐ 此后如竟没有炬火,我便是唯一的光。 ⭐

Go语言中的指针

Go语言中的函数传参都是值传递,当我们想要修改某个变量的时候,我们可以创建一个指向该变量地址的指针变量,传递数据使用指针,而无需拷贝数据。

类型指针不能进行偏移和运算。

Go语言中的指针操作非常简单,只需要记住两个符号&(取地址)和*(根据地址取值)

指针地址和指针类型

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用&字符放在变量前面对变量进行取地址操作。Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如: *int、 *int64、*string等。

指针的语法

一个指针变量指向了一个值的内存地址。(也就是我们声明了一个指针之后,可以像变量赋值一样,把一个值的内存地址放入到指针当中。)类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:

var var _name *var_type

var_type :为指针类型 var_name :为指针变量名 *:用于指定变量是作为一个指针。

package main

import "fmt"

func main() {
    var p *int
    fmt.Printf("p: %v\n", p)
    fmt.Printf("p: %T\n", p)
    var a int = 100
    p = &a
    fmt.Printf("p: %v\n", *p)

    var str *string
    fmt.Printf("str: %v\n", str)
    fmt.Printf("str: %T\n", str)
    s := "Y4y17"
    str = &s
    fmt.Printf("str: %v\n", *str)

    var bl *bool
    fmt.Printf("bl: %v\n", bl)
    fmt.Printf("bl: %T\n", bl)
    var b bool = true
    bl = &b
    fmt.Printf("bl: %v\n", *bl)
}

输出结果为:

指向数组的指针

定义语法

var ptr [MAX]*int //表示数组里面的元素的类型是指针类型

package main

import "fmt"

func main() {
    a := [3]int{1, 2, 3}
    var p [3]*int
    fmt.Printf("p: %v\n", p)
    for i := 0; i < len(a); i++ {
        p[i] = &a[i]
        fmt.Printf("p[i]: %v\n", *p[i])
    }
}

输出结果为:

Go语言中的类型定义和类型别名

Go语言类型定义

type Newtype Type

package main
import "fmt"

func main() {
    type Myint int
    var i Myint = 100
    fmt.Printf("i: %T,%v\n", i, i)
}

输出结果如下:

i: main.Myint,100

Go语言类型别名

type Newtype=Type
package main
import "fmt"
func main() {
	type Myint = int
    var i Myint = 100
    fmt.Printf("i: %T,%v\n", i, i)
}
i: int,100

Go语言中的类型定义和类型别名的区别

  1. 类型定义相当于定义了一个全新的类型,与之前的类型不同;但是类型别名并没有定义一个新的类型,而是使用一个别名来替换之前的类型

  1. 类型别名只会在代码中存在,在编译完成之后并不会存在该别名

  1. 因为类型别名和原来的类型是一致的,所以原来类型所拥有的方法,类型别名中也可以调用,但是如果是重新定义的一个类型,那么不可以调用之前的任何方法

Go语言中的结构体

在使用结构体之前我们需要定义一个结构体类型,之后通过定义的这个结构体类型在去定义结构体变量;语法结构如下:

type struct_variable_type struct{
member definition;
member definition;
......
member definition;
}	
type:结构体定义关键字
struct_variable_type:结构体类型名称
member definition:成员定义
package main

import "fmt"

func main() {
    type person struct {
        name string
        age  int
        sex  string
    }
    var tom person
    fmt.Printf("tom: %v\n", tom)
    tom.name = "tom"
    tom.sex = "man"
    tom.age = 20
    fmt.Printf("tom: %v\n", tom)
    fmt.Printf("tom.name: %v\n", tom.name)
}

输出的结果如下:

匿名结构体

package main

import "fmt"

func main() {
    var tom struct {	//匿名结构体在定义的时候不再使用type 而是var
        name string
        age  int
        sex  string
    }
    tom.name = "tom"
    tom.sex = "man"
    tom.age = 20
    fmt.Printf("tom: %v\n", tom)
    fmt.Printf("tom.name: %v\n", tom.name)
}

结构体的初始化

package main

import "fmt"

func main() {
    type person struct {
        name, email string
        age, id     int
    }
    //第一种初始化的方法:键值对的方式
    var tom person
    tom = person{
        name:  "tom",
        email: "tom@gmail.com",
        age:   20,
        id:    111,
    }
    fmt.Printf("tom: %v\n", tom)
    //第二种初始化的方法:列表的方式
    var Y4y17 person
    Y4y17 = person{
        //这种初始化的方法,必须按照结构体成员定义的顺序进行初始化
        "Y4y17",
        "Y4y17@gmail.com",
        20,
        16,
    }
    fmt.Printf("Y4y17: %v\n", Y4y17)
    //第三种初始化的方法:支持短变量赋值
    Mary := person{
        //部分赋值也是可以的
        name: "Mary",
        id:   22,
    }
    fmt.Printf("Mary: %v\n", Mary)
}
输出结果如下:
tom: {tom tom@gmail.com 20 111}
Y4y17: {Y4y17 Y4y17@gmail.com 20 16}
Mary: {Mary  0 22}

结构体指针

package main

import (
    "fmt"
)
//普通的指针变量
func test1() {
    var name string = "Y4y17"
    var nm *string
    nm = &name
    fmt.Printf("name: %v\n", name)
    fmt.Printf("nm: %v\n", nm)
    fmt.Printf("nm: %v\n", *nm)
}
//结构体指针
func test2() {
    type person struct {
        name string
        age  int
        id   int
    }
    var p_struct *person
    //这里存在3种赋值的方式
    //第一种方式:
    p_struct = &person{
        name: "Y4y17",
        age:  20,
        id:   17,
    }
    fmt.Printf("p_struct: %v\n", *p_struct)
    //第二种方式
    var tom person = person{"tom", 20, 17}
    var p_struct1 *person
    p_struct1 = &tom
    fmt.Printf("p_struct1: %v\n", *p_struct1)
    //第三种方式:
    var p_struct2 = new(person)
    p_struct2.age = 22
    p_struct2.name = "Mary"
    fmt.Printf("p_struct2: %v\n", *p_struct2)
}

func main() {
    test2()
}
输出结构如下:
p_struct: {Y4y17 20 17}
p_struct1: {tom 20 17}
p_struct2: {Mary 22 0}

结构体作为函数的参数

package main

import "fmt"

type person struct {
    name string
    age  int
    id   int
}

func show_person(per person) {
    per.name = "Y4y17"
    per.age = 24
    per.id = 17
    fmt.Printf("per: %v\n", per)
}
func main() {
    Mary := person{
        name: "Mary",
        age:  23,
        id:   99,
    }
    fmt.Printf("Mary: %v\n", Mary)
    fmt.Printf("--------------------------\n")
    show_person(Mary)
    fmt.Printf("Mary: %v\n", Mary)
}
Mary: {Mary 23 99}
--------------------------
per: {Y4y17 24 17}
Mary: {Mary 23 99}
package main

import "fmt"

type person struct {
    name string
    age  int
    id   int
}

func show_person(per *person) {
    per.name = "Y4y17"
    per.age = 24
    per.id = 17
    fmt.Printf("per: %v\n", *per)
}
func main() {
    Mary := person{
        name: "Mary",
        age:  23,
        id:   99,
    }
    fmt.Printf("Mary: %v\n", Mary)
    fmt.Printf("--------------------------\n")
    show_person(&Mary)
    fmt.Printf("Mary: %v\n", Mary)
}
修改一下代码,使得变成传递地址的方式:
Mary: {Mary 23 99}
--------------------------
per: {Y4y17 24 17}
Mary: {Y4y17 24 17}

结构体的嵌套

package main

import "fmt"

type person struct {
    name string
    age  int
    id   int
    cat  cat	//结构体中嵌套着一个cat结构体
}

type cat struct {
    name  string
    age   int
    color string
}

func main() {
    cat := cat{
        name:  "敢敢",
        age:   1,
        color: "grey",
    }
    Y4y17 := person{
        name: "Y4y17",
        age:  23,
        id:   17,
        cat:  cat,
    }
    fmt.Printf("Y4y17: %v\n", Y4y17)
    fmt.Printf("Y4y17.cat.name: %v\n", Y4y17.cat.name)
}
Y4y17: {Y4y17 23 17 {敢敢 1 grey}}
Y4y17.cat.name: 敢敢

Go语言中的方法

go语言没有面向对象的特性,也没有类对象的概念。但是,可以使用结构体来模拟这些特性,我们都知道面向;象里面有类方法等概念。我们也可以声明一些方法,属于某个结构体。

Go语言方法的语法

Go中的方法,是一种特殊的函数,定义于struct之上(与struct关联、绑定),被称为struct的接受者(receiver)。通俗的讲,方法就是有接收者的函数。

语法格式如下:
type mytype struct{}
func (recv mytype) my_method( para) return_type {}
func (recv *mytype) my_method(para) return_type {}
mytype :定义一个结构体
recv∶接受该方法的结构体(receiver)my_method:方法名称
para :参数列表
return_type :返回值类型

从语法格式可以看出,一个方法和一个函数非常相似,多了一个接受类型。

package main

import "fmt"

type person struct {
	name string
}

func (per person) eat() {
	fmt.Printf("%v eating...\n", per.name)
}
func (per person) sleep() {
	fmt.Printf("%v sleeping...\n", per.name)
}
func main() {
	var tom person
	tom.name = "tom"
	tom.eat()
	tom.sleep()
}
package main

import "fmt"

type customer struct {
    name string
}

func (cus customer) login(name string, pwd string) bool {
    if name == "tom" && pwd == "123" {
        return true
    } else {
        return false
    }
}
func main() {
    cus := customer{
        name: "tom",
    }
    b := cus.login("tom", "123")
    fmt.Printf("b: %v\n", b)
}

Go语言方法的注意事项

  1. 方法的receiver type并非一定要是struct类型,type定义的类型别名、slice、map、channel、func类型等都可以。

  1. struct结合它的方法就等价于面向对象中的类。只不过struct可以和它的方法分开,并非一定要属于同一个文件,但必须属于同一个包。

  1. 方法有两种接收类型: (T Type)和(T *Type),它们之间有区别。

  1. 方法就是函数,所以Go中没有方法重载(overload)的说法,也就是说同一个类型中的所有方法名必须都唯一。如果receiver是一个指针类型,则会自动解除引用。

  1. 方法和type是分开的,意味着实例的行为(behavior)和数据存储(field)是分开的,但是它们通过receiver建立起关联关系。

Go语言方法接收者类型

分为值类型和指针类型

package main

import "fmt"

type customer struct {
    name string
}

//传值
func (cus customer) test1() {
    cus.name = "Y4y17"
}

//传递指针
func (cus *customer) test2() {
    cus.name = "Y4y17"
}
func main() {
    cus := customer{
        name: "tom",
    }
    cus.test1()
    fmt.Printf("cus: %v\n", cus)	//cus: {tom}
    cus.test2()
    fmt.Printf("cus: %v\n", cus)	//cus: {Y4y17}

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis中的动态SQL

Mybatis中的动态SQL 当存在多条件查询的SQL时&#xff0c;当用户某个条件的属性没有写时&#xff0c;就会存在问题&#xff0c;在test中则不能很好的运行 所以Mybatis提出了动态SQL。 即判断用户是否输入了某个属性 动态SQL中的一些问题 方法一 这个里的and是为了确保if条…

三天吃透MySQL八股文(2023最新整理)

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…

口红品牌管理APP

伴随着科技的发展&#xff0c;多条产业和产品已经走上了智能化的道路&#xff0c;口红也是如此&#xff0c;口红的品牌众多&#xff0c;格式&#xff0c;色号更是令人难以区分&#xff0c;为了便于顾客选购和产品的科技化整理销售&#xff0c;利用课程所学知识&#xff0c;基于…

服务搭建篇(六) Kafka + Zookeeper集群搭建

一.Zookeeper 1.什么是Zookeeper ZooKeeper 是一个开源的分布式协调框架&#xff0c;是Apache Hadoop 的一个子项目&#xff0c;主要 用来解决分布式集群中应用系统的一致性问题。Zookeeper 的设计目标是将那些复杂且容 易出错的分布式一致性服务封装起来&#xff0c;构成一个…

linux pybind11 python c++ 混合编程(包括具体版本匹配的设置)

pybind11的处理过程 我首先安装了pybind&#xff0c;参考了许多教程&#xff0c;但很多教程的貌似都来自微软导出pyd的方法&#xff0c;但是实际上linux下导出so文件而非pyd文件&#xff0c;后续运行的实例来自https://github.com/tdegeus/pybind11_examples&#xff08;代码就…

设计模式(十一)----结构型模式之装饰者模式

1、概述 我们先来看一个快餐店的例子。 快餐店有炒面、炒饭这些快餐&#xff0c;可以额外附加鸡蛋、火腿、培根这些配菜&#xff0c;当然加配菜需要额外加钱&#xff0c;每个配菜的价钱通常不太一样&#xff0c;那么计算总价就会显得比较麻烦。 使用继承的方式存在的问题&…

为多态基类声明virtual析构函数

我们知道&#xff0c;有时会让一个基类指针指向用 new 运算符动态生成的派生类对象&#xff08;类似接口的作用&#xff09;&#xff1b;同时&#xff0c;用 new 运算符动态生成的对象都是通过 delete 指向它的指针来释放的。如果一个基类指针指向用 new 运算符动态生成的派生类…

算法23:多叉树_派对的最大快乐值

公司的每个员工都符合 Employee 类的描述。整个公司的人员结构可以看作是一棵标准的、 没有环的多叉树。树的头节点是公司唯一的老板。除老板之外的每个员工都有唯一的直接上级。 叶节点是没有任何下属的基层员工(subordinates列表为空)&#xff0c;除基层员工外&#xff0c;每…

MySQL知识点小结

事务 进行数据库提交操作时使用事务就是为了保证四大特性,原子性,一致性,隔离性,持久性Durability. 持久性:事务一旦提交,对数据库的改变是永久的. 事务的日志用于保存对数据的更新操作. 这个操作T1事务操作的会发生丢失,因为最后是T2提交的修改,而且T2先进行一次查询,按照A…

线性回归算法和逻辑斯谛回归算法详细介绍及其原理详解

相关文章 K近邻算法和KD树详细介绍及其原理详解朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解决策树算法和CART决策树算法详细介绍及其原理详解线性回归算法和逻辑斯谛回归算法详细介绍及其原理详解 文章目录相关文章前言一、线性回归二、逻辑斯谛回归总结前言 今天给大家…

2020 NOC 编程猫创新编程全国决赛小学组第一部分(客观题)

Q1. 某角色的造型区及未完成的脚本如下,当前造型名称为猫,若想切换到熊冬眠的 浩型,变量次数的值不可能为( ) A. 2 B. 3 C. 4 D. 5 Q2. 运行下图所示脚本,角色的运动轨迹为( ) Q3. 运行脚本,变量“y”的值为( ) A. 200 B. 2200 C. 2000 D. 4000 Q4. 运行…

盘点:9款身份和访问管理工具

身份和访问管理&#xff08;IAM&#xff09;长期以来一直是安全领导者职业生涯的关键“试炼场”&#xff0c;许多人在身份技术部署方面做出了事关成败的决定。 确保安全访问和身份管理是网络安全态势的两大基础 。同时&#xff0c;人员、应用程序和系统登录的方式以及它们彼此集…

以业务行为驱动的反入侵安全能力建设

0x0 背景 最近听到一些甲方安全领域的专家分享了部分安全建设的经验&#xff0c;对安全运营下的反入侵技术能力建设有了些新的看法&#xff0c;依靠单个/多个异构的安全产品的关联能力形成的安全中台并不能在实际的攻防对抗当中占据主动地位&#xff0c;且很容易达到一个天花板…

Mr. Cappuccino的第45杯咖啡——Kubernetes之部署SpringBoot项目

Kubernetes之部署SpringBoot项目创建一个SpringBoot项目将SpringBoot项目打成Jar包使用Dockerfile制作镜像部署SpringBoot项目创建一个SpringBoot项目 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache…

一、前端稳定性规约该如何制定

前言 稳定性是数学或工程上的用语&#xff0c;判别一系统在有界的输入是否也产生有界的输出。若是&#xff0c;称系统为稳定&#xff1b;若否&#xff0c;则称系统为不稳定。 前端稳定性的体系建设大约可以分为了发布前&#xff0c;发布后&#xff0c;以及事故解决后三个阶段…

建立做机器学习项目的范式

建立起做机器学习项目的范式&#xff0c;萃取出核心步骤&#xff0c;避免后面做项目没有明确的方向。 核心步骤&#xff1a; 1、明确自己想做什么样的项目&#xff0c;感兴趣的领域&#xff1b; 2、找到满足项目的数据集&#xff0c;开源的或者自建数据集&#xff1b; 数据…

《数据结构》二叉树面试题

&#x1f451;作者主页&#xff1a;Java冰激凌 &#x1f4d6;专栏链接&#xff1a;数据结构 目录 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先力扣 思路分析 代码 思路拓展 根据一棵树的前序遍历与中序遍历构造二叉树。力扣 思路分析 代码 根据一棵树的中序遍历与…

Linux系统看门狗应用编程

目录看门狗应用编程介绍打开设备获取设备支持哪些功能&#xff1a;WDIOC_GETSUPPORT获取/设置超时时间&#xff1a;WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT开启/关闭看门狗&#xff1a;WDIOC_SETOPTIONS喂狗&#xff1a;WDIOC_KEEPALIVE看门狗应用编程实战在产品化的嵌入式系统中&…

[计算机网络(第八版)]第二章 物理层(章节测试/章节作业)

章节作业 带答案版 选择题 (单选题)双绞线是用两根绝缘导线绞合而成的&#xff0c;绞合的目的是&#xff08; &#xff09;。 A. 减少干扰 B. 提高传输速度 C. 增大传输距离 D. 增大抗拉强度(单选题)在电缆中采用屏蔽技术可以带来的好处主要是&#xff08; &#xff09;。 A…

DNS 域名解析

介绍域名 网域名称&#xff08;英语&#xff1a;Domain Name&#xff0c;简称&#xff1a;Domain&#xff09;&#xff0c;简称域名、网域。 域名是互联网上某一台计算机或计算机组的名称。 域名可以说是一个 IP 地址的代称&#xff0c;目的是为了便于记忆。例如&#xff0c…