6 接口、多態(tài)、斷言、項(xiàng)目【Go語言教程】
1 接口
1.1 概念
Golang 中 多態(tài)特性主要是通過接口來體現(xiàn)的。
- interface 類型可以定義一組方法,但是這些不需要實(shí)現(xiàn)。并且 interface 不能包含任何變量。到某個自定義類型(比如結(jié)構(gòu)體 Phone)要使用的時候,在根據(jù)具體情況把這些方法寫出來(實(shí)現(xiàn))。
說明:
- 接口里的所有方法都沒有方法體,即接口的方法都是沒有實(shí)現(xiàn)的方法。接口體現(xiàn)了程序設(shè)計的多態(tài)和高內(nèi)聚低偶合的思想。
- Golang 中的接口,不需要顯式的實(shí)現(xiàn)。只要一個變量,含有接口類型中的所有方法,那么這個變量就實(shí)現(xiàn)這個接口。因此,Golang 中沒有 implement 這樣的關(guān)鍵字
1.2 使用場景及注意細(xì)節(jié)
- 接口本身不能創(chuàng)建實(shí)例,但是可以指向一個實(shí)現(xiàn)了該接口的自定義類型的變量(實(shí)例)
package main
import (
"fmt"
_ "go_code/project01/main/model"
)
//定義一個A接口
type AInterface interface {
Say()
}
type Stu struct {
Name string
}
//結(jié)構(gòu)體Stu實(shí)現(xiàn)了AInterface中的所有方法,相當(dāng)于Stu實(shí)現(xiàn)了AInterface
func (s Stu) Say(){
fmt.Println("stu Say()...")
}
func main(){
var stu Stu //結(jié)構(gòu)體變量,實(shí)現(xiàn)了Say() 實(shí)現(xiàn)了AInterface
var a AInterface = stu
a.Say()
//stu Say()...
}
- 接口中所有的方法都沒有方法體,即都是沒有實(shí)現(xiàn)的方法。
- 在 Golang 中,一個自定義類型需要將某個接口的所有方法都實(shí)現(xiàn),我們說這個自定義類型實(shí)現(xiàn)了該接口。
- 一個自定義類型只有實(shí)現(xiàn)了某個接口,才能將該自定義類型的實(shí)例(變量)賦給接口類型
- 只要是自定義數(shù)據(jù)類型,就可以實(shí)現(xiàn)接口,不僅僅是結(jié)構(gòu)體類型。
//自定義一個integer
type integer int
type AInteger interface {
Say()
}
func (i integer) Say(){
fmt.Println("integer Say i=", i)
}
func main(){
var i integer = 10
var b AInteger = i
b.Say() //integer Say i= 10
}
- 一個自定義類型可以實(shí)現(xiàn)多個接口
- Golang 接口中不能有任何變量
- 一個接口(比如 A 接口)可以繼承多個別的接口(比如 B,C 接口),這時如果要實(shí)現(xiàn) A 接口,也必須將 B,C 接口的方法也全部實(shí)現(xiàn)。
![]()
- interface 類型默認(rèn)是一個指針(引用類型),如果沒有對 interface 初始化就使用,那么會輸出 nil
空接口 interface{} 沒有任何方法,所以所有類型都實(shí)現(xiàn)了空接口, 即我們可以把任何一個變量賦給空接口
//定義一個T空接口
type T interface {
}
type Stu struct {
Name string
}
func main(){
var stu Stu
stu.Name = "jack"
var t T = stu
fmt.Println(t) //{jack}
var t2 interface{} = stu
var num1 float64 = 8.9
t2 = num1
t = num1
fmt.Println(t2, t) // 8.9 8.9
}
1.3 接口與繼承的區(qū)別與聯(lián)系
- 當(dāng) A 結(jié)構(gòu)體繼承了 B 結(jié)構(gòu)體,那么 A 結(jié)構(gòu)就自動的繼承了 B 結(jié)構(gòu)體的字段和方法,并且可以直接使用
- 當(dāng) A 結(jié)構(gòu)體需要擴(kuò)展功能,同時不希望去破壞繼承關(guān)系,則可以去實(shí)現(xiàn)某個接口即可,因此我們可以認(rèn)為:實(shí)現(xiàn)接口是對繼承機(jī)制的補(bǔ)充.
- 實(shí)現(xiàn)接口可以看作是對 繼承的一種補(bǔ)充
- 接口和繼承解決的解決的問題不同
繼承的價值主要在于:解決代碼的復(fù)用性和可維護(hù)性。
接口的價值主要在于:設(shè)計,設(shè)計好各種規(guī)范(方法),讓其它自定義類型去實(shí)現(xiàn)這些方法。
- 接口比繼承更加靈活 Person Student BirdAble LittleMonkey
接口比繼承更加靈活,繼承是滿足 is - a 的關(guān)系,而接口只需滿足 like - a 的關(guān)系。
- 接口在一定程度上實(shí)現(xiàn)代碼解耦
2 多態(tài)
2.1 概念
變量(實(shí)例)具有多種形態(tài)。面向?qū)ο蟮牡谌筇卣鳎?Go 語言,多態(tài)特征是通過接口實(shí)現(xiàn)的??梢园凑战y(tǒng)一的接口來調(diào)用不同的實(shí)現(xiàn)。這時接口變量就呈現(xiàn)不同的形態(tài)。
2.2 接口體現(xiàn)多態(tài)的兩種形式
①多態(tài)參數(shù)
在前面的 Usb 接口案例,Usb usb ,即可以接收手機(jī)變量,又可以接收相機(jī)變量,就體現(xiàn)了 Usb 接口 多態(tài)。
②多態(tài)數(shù)組
演示一個案例:給 Usb 數(shù)組中,存放 Phone 結(jié)構(gòu)體 和 Camera 結(jié)構(gòu)體變量
package main
import (
"fmt"
_ "go_code/project01/main/model"
)
//定義一個usb接口
type Usb interface{
Start()
Stop()
}
type Phone struct{
Name string
}
func (p Phone) Start(){
fmt.Println(p.Name + "手機(jī)開始工作....")
}
func (p Phone) Stop(){
fmt.Println(p.Name + "手機(jī)停止工作")
}
type Computer struct{
Name string
}
func (c Computer) Start(){
fmt.Println(c.Name + "電腦開始工作....")
}
func (c Computer) Stop(){
fmt.Println(c.Name + "電腦停止工作")
}
func main(){
var arr [3]Usb
arr[0] = Phone{"小米"}
arr[1] = Computer{"華碩"}
arr[2] = Phone{"華為"}
for i := 0; i < len(arr); i++ {
arr[i].Start()
arr[i].Stop()
fmt.Println()
}
}
3 類型斷言
3.1 概念
類型斷言,由于接口是一般類型,不知道具體類型,如果要轉(zhuǎn)成具體類型,就需要使用類型斷言, 具體的如下:
- 對上面代碼的說明:
- 在進(jìn)行類型斷言時,如果類型不匹配,就會報 panic, 因此進(jìn)行類型斷言時,要確保原來的空接口指向的就是斷言的類型- 如何在進(jìn)行斷言時,帶上檢測機(jī)制,如果成功就 ok,否則也不要報 panic
// 類型斷言(帶檢測的)
var x interface{}
var b2 float32 = 2.1
x = b2 //空接口,可以接收任意類型
// x => float32 [使用類型斷言]
// val, ok := x.(float32) //判斷x是否能轉(zhuǎn)換為float32
if y, ok := x.(float32); ok {
fmt.Println("convert success..")
fmt.Printf("y 的類型是 %T, 值是=%v", y, y)
} else {
fmt.Println("convert fail..")
}
fmt.Println("繼續(xù)執(zhí)行。。。")
//convert success..
//y 的類型是 float32, 值是=2.1繼續(xù)執(zhí)行。。。
3.2 實(shí)踐
給 Phone 結(jié)構(gòu)體增加一個特有的方法 call(), 當(dāng) Usb 接口接收的是Phone 變量時,還需要調(diào)用 call方法
package main
import (
"fmt"
_ "go_code/project01/main/model"
)
//定義一個usb接口
type Usb interface{
Start()
Stop()
}
type Phone struct{
Name string
}
func (p Phone) Start(){
fmt.Println(p.Name + "手機(jī)開始工作....")
}
func (p Phone) Stop(){
fmt.Println(p.Name + "手機(jī)停止工作")
}
//Phone多一個Call方法
func (p Phone) Call(){
fmt.Println(p.Name + "手機(jī)正在call...")
}
type Computer struct{
Name string
}
func (c Computer) Start(){
fmt.Println(c.Name + "電腦開始工作....")
}
func (c Computer) Stop(){
fmt.Println(c.Name + "電腦停止工作")
}
func main(){
var arr [3]Usb
arr[0] = Phone{"小米"}
arr[1] = Computer{"華碩"}
arr[2] = Phone{"華為"}
for i := 0; i < len(arr); i++ {
arr[i].Start()
//使用類型斷言判斷是否是手機(jī)
val, ok := arr[i].(Phone)
if ok {
val.Call()
}
arr[i].Stop()
fmt.Println()
}
}
4 項(xiàng)目
4.1 需求分析及UI圖
使用Go編譯一個客戶信息關(guān)系系統(tǒng)
- 模擬實(shí)現(xiàn)基于文本界面的《客戶信息管理軟件》。
- 該軟件能夠?qū)崿F(xiàn)對客戶對象的插入、修改和刪除(用切片實(shí)現(xiàn)),并能夠打印客戶明細(xì)表
-
主菜單頁面:
-
添加客戶頁面
-
修改客戶頁面
-
刪除客戶頁面
-
客戶列表頁面
4.2 分析及代碼實(shí)現(xiàn)
①分析
- 完成顯示項(xiàng)目主菜單和退出軟件
編寫 customerView.go ,另外可以把 customer.go 和 customerService.go 寫上.
涉及代碼:
- customerManage/model/customer.go
- customerManage/view/customerView.go
- 完成顯示客戶列表功能
- customerManage/model/customer.go
- customerManage/service/customerService.go[增加了兩個方法]
- customerManage/view/customerView.go
- 添加客戶功能實(shí)現(xiàn)
- customerManage/model/customer.go
- customerManage/service/customerService.go
- customerManage/service/customerView.go
- 刪除客戶功能實(shí)現(xiàn)
- customerManage/model/customer.go [沒有變化]
- customerManage/service/customerService.go
- customerManage/view/customerView.go
- 完善退出確認(rèn)功能
- 功能說明:
要求用戶在退出時提示 " 確認(rèn)是否退出(Y/N):",用戶必須輸入 y/n, 否則循環(huán)提示。- 思路分析:
需要編寫 customerView.go
②代碼實(shí)現(xiàn)
項(xiàng)目結(jié)構(gòu):
1. 完成顯示項(xiàng)目主菜單和退出軟件
- customerManger/model/customer.go
package model
//定義Customer結(jié)構(gòu)體
type Customer struct {
Id int
Name string
Gender string
Age int
Phone string
Email string
}
//工廠模式實(shí)現(xiàn)構(gòu)造函數(shù)效果
func NewCustomer(id int, name string, gender string, age int, phone string, email string) Customer{
//TODO 未來可以在此對傳入的參數(shù)合法性進(jìn)行校驗(yàn)
return Customer {
Id : id,
Name : name,
Gender : gender,
Age : age,
Phone : phone,
Email : email,
}
}
- customerManager/service/customerService.go
package service
import (
"../model/"
)
//該 CustomerService, 完成對 Customer 的操作,包括
//增刪改查
type customerService {
//定義用戶切片,用于存儲用戶信息
customers []model.Customer
//用于后面執(zhí)行用戶id自增效果
//聲明一個字段,表示當(dāng)前切片含有多少個客戶
//該字段后面,還可以作為新客戶的 id+1
customerCount int
}
- customerManager/view/customerView.go
package main
import (
"fmt"
)
type customerView struct {
key string //用于接收用戶輸入,從而進(jìn)行下一步操作
loop bool //是否循環(huán)展示主菜單
}
func (this *customerView) mainMenu(){
for {
fmt.Println("-----------------客戶信息管理軟件 ")
fmt.Println(" 1 添 加 客 戶")
fmt.Println(" 2 修 改 客 戶")
fmt.Println(" 3 刪 除 客 戶")
fmt.Println(" 4 客 戶 列 表")
fmt.Println(" 5 退 出")
fmt.Print("請選擇(1-5):")
//接收用戶輸入
fmt.Scanln(&this.key)
switch this.key {
case "1" :
fmt.Println("添加用戶")
case "2" :
fmt.Println("修改用戶")
case "3":
fmt.Println("刪除用戶")
case "4":
fmt.Println("客戶列表")
case "5":
fmt.Println("退出")
this.loop = false
default :
fmt.Println("輸入有誤,請重新輸入..")
}
if !this.loop {
break
}
}
fmt.Println("您退出了管理系統(tǒng)..")
}
func main(){
//在main函數(shù)中創(chuàng)建customerView并運(yùn)行主菜單
customerView := customerView {
key : "",
loop : true,
}
customerView.mainMenu()
}
2. 完成顯示客戶列表功能
- model/customer.go:
package model
import(
"fmt"
)
//定義Customer結(jié)構(gòu)體
type Customer struct {
Id int
Name string
Gender string
Age int
Phone string
Email string
}
//工廠模式實(shí)現(xiàn)構(gòu)造函數(shù)效果
func NewCustomer(id int, name string, gender string, age int, phone string, email string) Customer{
//TODO 未來可以在此對傳入的參數(shù)合法性進(jìn)行校驗(yàn)
return Customer {
Id : id,
Name : name,
Gender : gender,
Age : age,
Phone : phone,
Email : email,
}
}
//定義返回信息方法【toString】
func (this Customer) GetInfo() string {
info := fmt.Sprintf("%v\t%v\t%v\t%v\t%v\t%v\t", this.Id,
this.Name, this.Gender, this.Age, this.Phone, this.Email)
return info
}
- service/customerService.go:
package service
import (
"go_code/customerManage/model"
)
//該 CustomerService, 完成對 Customer 的操作,包括
//增刪改查
type CustomerService struct {
//定義用戶切片,用于存儲用戶信息
customers []model.Customer
//用于后面執(zhí)行用戶id自增效果;
//聲明一個字段,表示當(dāng)前切片含有多少個客戶
//該字段后面,還可以作為新客戶的 id+1
customerCount int
}
func NewCustomerService() *CustomerService {
//為了可以看到有客戶在切片中,我們在這里初始化一個客戶
customerService := &CustomerService{}
customerService.customerCount = 1
c := model.NewCustomer(1, "張三", "男", 20, "112", "zs@163.com")
customerService.customers = append(customerService.customers, c)
return customerService
}
//返回客戶切片
func (this *CustomerService) List() []model.Customer{
return this.customers
}
- view/customerView.go:
package main
import (
"fmt"
"go_code/customerManage/service"
)
type customerView struct {
key string //用于接收用戶輸入,從而進(jìn)行下一步操作
loop bool //是否循環(huán)展示主菜單
//指針類型,保證每次調(diào)用時候都是一個
customerService *service.CustomerService
}
func (this *customerView) mainMenu(){
for {
fmt.Println("-----------------客戶信息管理軟件 ")
fmt.Println(" 1 添 加 客 戶")
fmt.Println(" 2 修 改 客 戶")
fmt.Println(" 3 刪 除 客 戶")
fmt.Println(" 4 客 戶 列 表")
fmt.Println(" 5 退 出")
fmt.Print("請選擇(1-5):")
//接收用戶輸入
fmt.Scanln(&this.key)
switch this.key {
case "1" :
fmt.Println("添加用戶")
case "2" :
fmt.Println("修改用戶")
case "3":
fmt.Println("刪除用戶")
case "4":
this.list()
case "5":
fmt.Println("退出")
this.loop = false
default :
fmt.Println("輸入有誤,請重新輸入..")
}
if !this.loop {
break
}
}
fmt.Println("您退出了管理系統(tǒng)..")
}
func (this *customerView) list(){
customers := this.customerService.List()
//顯示
fmt.Println("---------------------------客戶列表 ")
fmt.Println("編號\t 姓名\t 性別\t 年齡\t 電話\t 郵箱")
for i := 0; i < len(customers); i++ {
fmt.Println(customers[i].GetInfo())
}
fmt.Printf("\n-------------------------客戶列表完成 \n\n")
}
func main(){
//在main函數(shù)中創(chuàng)建customerView并運(yùn)行主菜單
customerView := customerView {
key : "",
loop : true,
customerService : service.NewCustomerService(),
}
customerView.mainMenu()
}
3. 添加刪除功能實(shí)現(xiàn)
①添加功能
model/customer.go:
//定義不帶ID創(chuàng)建Customer的方法[customer的id由customerNum來判斷]
func NewCustomer2(name string, gender string, age int, phone string, email string) Customer {
return Customer {
Name : name,
Gender : gender,
Age : age,
Phone : phone,
Email : email,
}
}
service/customerService.go:
//添加用戶到customers切片
func (this *CustomerService) Add(customer model.Customer) bool {
//我們確定一個分配id的規(guī)則,就是添加的順序【customerNum(customerCount)】
this.customerCount++
customer.Id = this.customerCount
this.customers = append(this.customers, customer)
return true
}
view/customerView.go:
//添加customer
func(this *customerView) add(){
fmt.Println(" 添加客戶 ")
fmt.Println("姓名:")
name := ""
fmt.Scanln(&name)
fmt.Println("性別:")
gender := ""
fmt.Scanln(&gender)
fmt.Println("年齡:")
age := 0
fmt.Scanln(&age)
fmt.Println("電話:")
phone := ""
fmt.Scanln(&phone)
fmt.Println("郵箱:")
email := ""
fmt.Scanln(&email)
//創(chuàng)建一個新的customer實(shí)例【id沒有讓用戶輸入,而是直接從customerCount中獲取】
customer := model.NewCustomer2(name, gender, age, phone, email)
if this.customerService.Add(customer) {
fmt.Println(" 添加完成 ")
}else {
fmt.Println(" 添加失敗 ")
}
}
customerView中調(diào)用方法:
②刪除功能
view/customerView.go:
//刪除用戶
func (this *customerView) delete(){
fmt.Println("-----------------刪除用戶-----------------")
fmt.Println("請選擇待刪除客戶編號(-1退出):")
id := -1
fmt.Scanln(&id)
if id == -1 {
return //放棄刪除操作
}
flag := false
choice := ""
for {
if flag {
break
}
fmt.Println("確認(rèn)是否刪除(Y/N):")
fmt.Scanln(&choice)
if choice == "y" || choice == "Y" {
flag = true
//調(diào)用customerService的Delete方法
if this.customerService.Delete(id) {
fmt.Println("-------------刪除完成-------------")
} else {
fmt.Println("------刪除失敗,輸入的id號不存在---")
}
} else if choice == "n" || choice == "N" {
flag = true
} else {
fmt.Println("輸入不合理,請重新輸入....")
}
}
}
4. 完善退出功能=>全部代碼
- model/customer.go:
package model
import(
"fmt"
)
//定義Customer結(jié)構(gòu)體
type Customer struct {
Id int
Name string
Gender string
Age int
Phone string
Email string
}
//工廠模式實(shí)現(xiàn)構(gòu)造函數(shù)效果
func NewCustomer(id int, name string, gender string, age int, phone string, email string) Customer{
//TODO 未來可以在此對傳入的參數(shù)合法性進(jìn)行校驗(yàn)
return Customer {
Id : id,
Name : name,
Gender : gender,
Age : age,
Phone : phone,
Email : email,
}
}
//定義不帶ID創(chuàng)建Customer的方法[customer的id由customerNum來判斷]
func NewCustomer2(name string, gender string, age int, phone string, email string) Customer {
return Customer {
Name : name,
Gender : gender,
Age : age,
Phone : phone,
Email : email,
}
}
//定義返回信息方法【toString】
func (this Customer) GetInfo() string {
info := fmt.Sprintf("%v\t%v\t%v\t%v\t%v\t%v\t", this.Id,
this.Name, this.Gender, this.Age, this.Phone, this.Email)
return info
}
- service/customerService.go:
package service
import (
"go_code/customerManage/model"
_ "fmt"
)
//該 CustomerService, 完成對 Customer 的操作,包括
//增刪改查
type CustomerService struct {
//定義用戶切片,用于存儲用戶信息
customers []model.Customer
//用于后面執(zhí)行用戶id自增效果;
//聲明一個字段,表示當(dāng)前切片含有多少個客戶
//該字段后面,還可以作為新客戶的 id+1
customerCount int
}
func NewCustomerService() *CustomerService {
//為了可以看到有客戶在切片中,我們在這里初始化一個客戶
customerService := &CustomerService{}
customerService.customerCount = 1
c := model.NewCustomer(1, "張三", "男", 20, "112", "zs@163.com")
customerService.customers = append(customerService.customers, c)
return customerService
}
//返回客戶切片
func (this *CustomerService) List() []model.Customer{
return this.customers
}
//添加用戶到customers切片
func (this *CustomerService) Add(customer model.Customer) bool {
//我們確定一個分配id的規(guī)則,就是添加的順序【customerNum(customerCount)】
this.customerCount++
customer.Id = this.customerCount
this.customers = append(this.customers, customer)
return true
}
//刪除用戶
func (this *CustomerService) Delete(id int) bool {
index := this.FindById(id)
//如果index == -1, 說明沒有這個用戶
if index == -1 {
return false
}
//如何從列表中刪除一個元素=>從[0,index)位置 + [index+1, 最后]
this.customers = append(this.customers[:index], this.customers[index+1:]...)
return true
}
//根據(jù)id查找用戶在切片中對應(yīng)下標(biāo),如果沒有則返回-1
func (this *CustomerService) FindById(id int) int {
index := -1
for i := 0; i < len(this.customers); i++ {
if this.customers[i].Id == id {
return i
}
}
return index
}
- view/cutomerView.go:
package main
import (
"fmt"
"go_code/customerManage/service"
"go_code/customerManage/model"
)
type customerView struct {
key string //用于接收用戶輸入,從而進(jìn)行下一步操作
loop bool //是否循環(huán)展示主菜單
//指針類型,保證每次調(diào)用時候都是一個
customerService *service.CustomerService
}
func (this *customerView) mainMenu(){
for {
fmt.Println("-----------------客戶信息管理軟件-----------------")
fmt.Println(" 1 添 加 客 戶")
fmt.Println(" 2 修 改 客 戶")
fmt.Println(" 3 刪 除 客 戶")
fmt.Println(" 4 客 戶 列 表")
fmt.Println(" 5 退 出")
fmt.Print("請選擇(1-5):")
//接收用戶輸入
fmt.Scanln(&this.key)
switch this.key {
case "1" :
this.add()
case "2" :
fmt.Println("更新用戶")
// this.update()
case "3":
this.delete()
case "4":
this.list()
case "5":
this.exit()
default :
fmt.Println("輸入有誤,請重新輸入..")
}
if !this.loop {
break
}
}
fmt.Println("您退出了管理系統(tǒng)..")
}
func (this *customerView) list(){
customers := this.customerService.List()
//顯示
fmt.Println("---------------------------客戶列表 ")
fmt.Println("編號\t 姓名\t 性別\t 年齡\t 電話\t 郵箱")
for i := 0; i < len(customers); i++ {
fmt.Println(customers[i].GetInfo())
}
fmt.Printf("\n-------------------------客戶列表完成 \n\n")
}
//添加customer
func(this *customerView) add(){
fmt.Println(" 添加客戶 ")
fmt.Println("姓名:")
name := ""
fmt.Scanln(&name)
fmt.Println("性別:")
gender := ""
fmt.Scanln(&gender)
fmt.Println("年齡:")
age := 0
fmt.Scanln(&age)
fmt.Println("電話:")
phone := ""
fmt.Scanln(&phone)
fmt.Println("郵箱:")
email := ""
fmt.Scanln(&email)
//創(chuàng)建一個新的customer實(shí)例【id沒有讓用戶輸入,而是直接從customerCount中獲取】
customer := model.NewCustomer2(name, gender, age, phone, email)
if this.customerService.Add(customer) {
fmt.Println(" 添加完成 ")
}else {
fmt.Println(" 添加失敗 ")
}
}
//刪除用戶
func (this *customerView) delete(){
fmt.Println("-----------------刪除用戶-----------------")
fmt.Println("請選擇待刪除客戶編號(-1退出):")
id := -1
fmt.Scanln(&id)
if id == -1 {
return //放棄刪除操作
}
flag := false
choice := ""
for {
if flag {
break
}
fmt.Println("確認(rèn)是否刪除(Y/N):")
fmt.Scanln(&choice)
if choice == "y" || choice == "Y" {
flag = true
//調(diào)用customerService的Delete方法
if this.customerService.Delete(id) {
fmt.Println("-------------刪除完成-------------")
} else {
fmt.Println("------刪除失敗,輸入的id號不存在---")
}
} else if choice == "n" || choice == "N" {
flag = true
} else {
fmt.Println("輸入不合理,請重新輸入....")
}
}
}
//退出功能
func (this *customerView) exit(){
fmt.Println("確認(rèn)是否退出(Y/N):")
for{
fmt.Scanln(&this.key)
if this.key == "Y" || this.key == "y" || this.key == "N" || this.key == "n" {
break
}
fmt.Println("你的輸入有誤,請重新輸入,確認(rèn)是否退出(Y/N):")
}
if this.key == "Y" || this.key == "y" {
this.loop = false
}
}
func main(){
//在main函數(shù)中創(chuàng)建customerView并運(yùn)行主菜單
customerView := customerView {
key : "",
loop : true,
customerService : service.NewCustomerService(),
}
customerView.mainMenu()
}
5 Go相關(guān)Bug合集
1. xxx is not in GOROOT
在項(xiàng)目中輸入以下代碼報錯:
import (
"fmt"
"go_code/customerManage/service"
)
package go_code/customerManage/service is not in GOROOT (E:\Go\go\src\go_code\customerManage\service)go
方法一:
關(guān)閉go mod
Go.mod是Golang1.11版本新引入的官方包管理工具用于解決之前沒有地方記錄依賴包具體版本的問題,方便依賴包的管理,可以理解為java中的maven;
go env -w GO111MODULE=off
方法二:文章來源:http://www.zghlxwxcb.cn/news/detail-443423.html
在項(xiàng)目根目錄下開啟mod文章來源地址http://www.zghlxwxcb.cn/news/detail-443423.html
go mod init
// 下載依賴
go mod tidy
到了這里,關(guān)于6 接口、多態(tài)、斷言、項(xiàng)目【Go語言教程】的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!