首页 > 其他分享 >一文带你玩透结构体和方法

一文带你玩透结构体和方法

时间:2022-10-02 22:34:33浏览次数:70  
标签:一文 fmt User func Println main 方法 string 结构

  1. 结构体的基本定义和使用
package main

import (
	"fmt"
)

//定义结构体类型User
type User struct {
	username string "用户名"
	password string "密码"
	mail     string "邮箱"
}

func main() {
	//初始化方式1
	var user User
	user.username = "ttr"
	user.password = "abc123"
	user.mail = "[email protected]"
	fmt.Println(user)

	//初始化方式2
	user1 := User{"chavis", "1qaz#EDC", "[email protected]"}
	fmt.Println(user1)

	//初始化方式3
	user2 := User{username: "root", password: "abc@9089", mail: "[email protected]"}
	fmt.Println(user2)
}
  1. 结构体嵌套
package main

import "fmt"

type Device struct {
	ip        string
	user      string
	pwd       string
	loginType string `登录类型`
}

type Idc struct {
	device Device
	num    int
	addr   string
}

func main() {
	idc := Idc{
		device: Device{ip: "10.1.1.1", user: "root", pwd: "1qaz#EDC", loginType: "ssh"},
		num:    907745,
		addr:   "GZ",
	}
	fmt.Println(idc)
}

输出:

{{10.1.1.1 root 1qaz#EDC ssh} 907745 GZ}
  1. 结构体实例化的3种方式

结构体定义完后是没有分配内存的,需要实例话之后才可以使用结构体。实例化有3种方式:变量定义、new、&符号。

package main

import "fmt"

type Host struct {
	user string
	pwd  string
}

func main() {
	// 变量定义的方式实例化结构体
	var h Host
	h.user = "root"
	h.pwd = "1qaz#EDC"
	fmt.Println(h)

	// new的方式实例化结构体
	var h1 = new(Host)
	h1.user = "admin"
	h1.pwd = "2345#EDC"
	fmt.Println(h1)

	// &符号定义的方式实例化结构体
	var h2 = &Host{}
	h2.user = "ttr"
	h2.pwd = "98768#EDC"
	fmt.Println(h2)
}
  1. 带标签的结构体,标签用于对字段进行说明
package main

import (
	"fmt"
)

type User struct {
	username string "用户名" //"用户名"是标签
	password string "密码"
	mail     string "邮箱"
}

func main() {
	user := User{username: "ttr", password: "1qaz@WSX", mail: "[email protected]"}
	fmt.Println(user)
}
  1. 匿名结构体

匿名结构体不用类型名称,不用使用type关键字定义。

package main

import "fmt"

func main() {
	//基本结构
	user := struct {
	}{}
	fmt.Println(user)

	//定义和初始化
	user1 := struct {
		name string
		age  int
	}{
		"tantianran",
		18,
	}
	fmt.Println(user1)
	fmt.Println(user1.name)
	fmt.Println(user1.age)
}
  1. 给结构体User添加方法show(),该方法输出一个hello
package main

import (
	"fmt"
)

type User struct {
	name string
	age  int
}

func (User) show() {
	fmt.Println("hello")
}

func main() {
	u := User{name: "ttr", age: 17}
	u.show()
}
  1. 给结构体添加方法,并将已经初始化好的值可以在方法内拿到
package main

import (
	"fmt"
)

type User struct {
	name string
	age  int
}

func (u User) show() {
	fmt.Println(u.name, u.age)
}

func main() {
	u := User{name: "ttr", age: 17} //初始化并实例化
	u.show() //调用方法

}

输出:

ttr 17
  1. 给结构体添加方法,并将已经初始化好的值可以在方法内进行修改,注意这里是*User,也就是指针类型
package main

import (
	"fmt"
)

type User struct {
	name string
	age  int
}

func (u *User) chage() {
	u.name = "chavis"
	u.age = 30
}

func main() {
	u := User{name: "ttr", age: 17} //初始化和实例化
	fmt.Println(u.name, u.age)      //修改前
	u.chage()                       //调用chage方法修改已经初始化好的值
	fmt.Println(u.name, u.age)      //修改后
}

输出:

ttr 17
chavis 30

如果不是指针类型,在方法内是无法修改外部已经初始化好的结构体的值,看下面效果

package main

import "fmt"

type User struct {
	name string
	age  int
}

func (u User) chage() {
	u.name = "chavis"
	u.age = 30
}

func main() {
	u := User{name: "ttr", age: 17}
	u.chage()
	fmt.Println(u)
}

输出:

{ttr 17}

看上面的效果可以知道没有被修改成功,因为是值传递,而如果是指针的话,就是直接指向了已经初始化了值且实例化完并赋给变量u所在的那块内存地址。

  1. 在上一个栗子的基础上做改造,使其有返回值,且返回值类型为指针类型
package main

import (
	"fmt"
)

type User struct {
	name string
	age  int
}

func (u *User) chage() *User {
	u.name = "chavis"
	u.age = 30
	return u
}

func main() {
	u := User{name: "ttr", age: 17}
	a := u.chage()
	fmt.Println(*a)
}

输出:

{chavis 30}
  1. 在一个普通的函数内修改外部结构体的值
package main

import "fmt"

type User struct {
	name string
	age  int
}

func chage(data *User) {
	data.name = "tantianran"
	data.age = 30
}

func main() {
	u := &User{name: "ttr", age: 17}
	chage(u)
	fmt.Println(*u)

	//也可以这样
	u1 := User{name: "ttr", age: 17}
	chage(&u1)
	fmt.Println(u1)
}
  1. 任意的类型也都是可以添加方法的,比如给int类型添加一个方法
package main

import "fmt"

type MyInt int

func (x MyInt) check() bool {
	if x > 100 {
		return true
	} else {
		return false
	}
}

func main() {
	a := MyInt(56)
	ret := a.check()
	fmt.Println(ret)
}

输出:

false
  1. 在上一个栗子的基础上,做一个加法,案例1
package main

import "fmt"

type MyInt int

func (x MyInt) add(y MyInt) MyInt {
	return x + y
}

func main() {
	a := MyInt(56)
	ret := a.add(54)
	fmt.Println(ret)
}

输出:

110
  1. 结构体转成json
package main

import (
	"encoding/json"
	"fmt"
)

type Host struct {
	Hostname string
	Ip       string
}

func main() {
	h := Host{
		Hostname: "web01",
		Ip:       "10.1.1.23",
	}
	if jsonStr, err := json.Marshal(h); err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(string(jsonStr))
	}
}

输出:

{"Hostname":"web01","Ip":"10.1.1.23"}

注意:结构体的字段首写字母要大写,否则json包无法读取到字段,进而转换失败(报错),Go语言是通过首字母的大小写来控制访问权限。无论是方法,变量,常量或是自定义的变量类型,如果首字母大写,则可以被外部包访问,反之则不可以。而结构体中的字段名,如果首字母小写的话,则该字段无法被外部包访问和解析。

  1. 刚说到结构体的字段首写字母要大写,如果想转换成json后首字母是小写,可以增加标签来做到,看下面代码
package main

import (
	"encoding/json"
	"fmt"
)

type Host struct {
	Hostname string `json:"hostname"` //标签加在这里
	Ip       string `json:"ip"` //标签加在这里
}

func main() {
	h := Host{
		Hostname: "web01",
		Ip:       "10.1.1.23",
	}
	if jsonStr, err := json.Marshal(h); err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(string(jsonStr))
	}
}

输出:

{"hostname":"web01","ip":"10.1.1.23"}
  1. 将json解析回结构体
package main

import (
	"encoding/json"
	"fmt"
)

type Host struct {
	Hostname string
	Ip       string
}

func main() {
	jsonData := `{"hostname":"web01","ip":"10.1.1.23"}`
	var h Host
	if err := json.Unmarshal([]byte(jsonData), &h); err != nil {
		fmt.Println("Error =", err)
		return
	}
	fmt.Println(h.Hostname)
	fmt.Println(h.Ip)
	fmt.Println(h)
}

输出:

web01
10.1.1.23
{web01 10.1.1.23}

本文装载于:https://mp.weixin.qq.com/s/g62pZW8h_vUbx-SQyBVw_g

标签:一文,fmt,User,func,Println,main,方法,string,结构
From: https://www.cnblogs.com/ttropsstack/p/16749639.html

相关文章

  • 循环结构
    循环结构while循环语法格式:While(布尔表达式){//循环内容}while(true):死循环publicstaticvoidmain(String[]args){        //计算1+2+3+...+100=?   ......
  • java学习之:类和对象、语句块、方法、递归结构!
    语句块和方法语句块语句块确定了局部变量的作用域。语句块嵌套,但是不能在两个嵌套的块内声明同名的变量。语句块可以使用语句块外的变量,语句块中定义的变量作用域只限于语句......
  • d有相同名类方法重载不适用于基类
    ​​原文​​​仅在基类上​​提供​​正确​​重载​​,而派生类上包含​​不正确​​重载时,编译器不会检查​​基类重载​​.如果​​派生类​​没有任何重载,则它可以......
  • 【Java】01基础-05 方法
    1.方法概述1.1方法的概念方法(method)是将具有独立功能的代码块组织成为一个整体,使其具有特殊功能的代码集注意:方法必须先创建才可以使用,该过程成为方法定义方法创建后并不......
  • Java方法详解
    JAVA方法详解Symtem.out.println()类对象方法JAVA方法是语句的集合,它们在一起执行一个功能方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在......
  • 数据结构与算法【Java】09---多路查找树
    目录前言1、二叉树与B树1.1、二叉树的问题分析1.2、多叉树1.3、B树的基本介绍2、2-3树2.1、2-3树简介2.2、2-3树应用案例2.3、补充3、B树、B+树和B*树3.1、B树的简......
  • springboot开启单元测试的方法分享
    转自:​​http://www.java265.com/JavaFramework/SpringBoot/202206/3781.html​​SpringBoot:  SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spri......
  • 1.3w字,一文详解死锁!
    死锁(DeadLock)指的是两个或两个以上的运算单元(进程、线程或协程),都在等待对方停止执行,以取得系统资源,但是没有一方提前退出,就称为死锁。1.死锁演示死锁的形成分为两个方......
  • 小猪学Java篇二十六(Switch多选择结构)
     packagecom.zhu.struct;publicclassSwitchDemo01{publicstaticvoidmain(String[]args){//case:【穿透现象】switch匹配一个具体的值,和if......
  • 查找字符串三种方法(截取子串,朴素匹配法,KMP匹配)——C语言描述
    查找字符串三种方法(截取子串,朴素匹配法,KMP匹配)——C语言描述目录查找字符串三种方法(截取子串,朴素匹配法,KMP匹配)——C语言描述0测试用例框架1查找字符串——截取字串方法......