1. 程式人生 > 其它 >Linux命令-sed

Linux命令-sed

介面

介面是自定義型別,是對其它型別行為的抽象

定義:

介面定義使用interface標識,聲明瞭一系列的函式簽名(函式名、函式引數、函式返回值)定義介面時可以指定介面名稱,在後續宣告介面變數時使用。

// 介面中主要定義行為和方法
type Sender interface { // 定義介面型別
	Send(to string, msg string) error
	SendAll(tos []string, msg string) error
}

type EmailSender struct {
}

func (s EmailSender) Send(to, msg string) error {
	fmt.Println("傳送郵件給:", to, "訊息內容是:", msg)
	return nil
}

func (s EmailSender) SendAll(tos []string, msg string) error {
	for _, to := range tos {
		s.Send(to, msg)
	}
	return nil
}

func do(send Sender) {
	send.Send("領導", "工作日誌")
}

func main() {
	var sender Sender = EmailSender{}     // 將結構體賦值給介面
	fmt.Printf("%T %v\n", sender, sender) // main.EmailSender {}

	sender.Send("kk", "早上好")           // 通過介面呼叫結構體的方法
	sender.SendAll([]string{"湯採玉", "湯文廣", "尹金秀"}, "大家早上好")
	do(sender) // 將介面傳入函式作為實參,後續函式呼叫可以使用介面的方法

	sender = &EmailSender{}
	do(sender)                           // 傳送郵件給: 領導 訊息內容是: 工作日誌 

}
  • 介面賦值給介面

當介面賦值給介面,新介面只能呼叫和老介面相同的函式方法,不能呼叫新藉口不具備的函式。

type Sender interface {                   // 定義介面型別
	Send(to string, msg string) error
	SendAll(tos []string, msg string) error
}

type SingSend interface {
	Send(to, msg string) error
}

func (s EmailSender) Send(to, msg string) error {
	fmt.Println("傳送郵件給:", to, "訊息內容是:", msg)
	return nil
}

func (s EmailSender) SendAll(tos []string, msg string) error {
	for _, to := range tos {
		s.Send(to, msg)
	}
	return nil
}


func main() {
    var sender Sender = EmailSender{}
	var ssender SingSend = sender    // 將介面賦值給介面,需要兩個介面具備相同型別函式
	ssender.Send("ttt", "早上好")    // 傳送郵件給: ttt 訊息內容是: 早上好
}

斷言

判斷一個介面能不能轉換為具體型別

type Sender interface {               // 定義介面型別
	Send(to string, msg string) error
	SendAll(tos []string, msg string) error
}
 
type SingSend interface {
	Send(to, msg string) error
}

type EmailSender struct {
}


func (s EmailSender) Send(to, msg string) error {
	fmt.Println("傳送郵件給:", to, "訊息內容是:", msg)
	return nil
}

func (s EmailSender) SendAll(tos []string, msg string) error {
	for _, to := range tos {
		s.Send(to, msg)
	}
	return nil
}

func main() {
	sender = &EmailSender{}
	var ssender SingSend = sender 
	ssender.Send("ttt", "早上好")    
  
   // 讓新介面變回原來的老介面,這時候sender01就有了老介面的功能
	sender01, ok := ssender.(Sender)        // 介面斷言,ssender轉換為Sender介面
	fmt.Printf("%T,%v\n", sender01, ok)     // *main.EmailSender,true
    sender01.SendAll([]string{"小販"}, "你好")	// 傳送郵件給: 小販 訊息內容是: 你好
}

型別查詢

.(type) 只能寫在case中

type SingSend interface {
	Send(to, msg string) error
}

type EmailSender struct {
}

main() {
    var sender Sender = EmailSender{}
    sender = &EmailSender{}
    var ssender SingSend = sender
        
    switch ssender.(type) {
	case EmailSender:
		fmt.Println("emailsender")
	case *EmailSender:
		fmt.Println("*emailsender")
	}   
}

/* 
*emailsender 
*/

介面匿名嵌入

type Sender interface {
	Send(msg string) error
}

type Reciver interface {
	Reciver() (string, error)
}

type Client interface {
	Sender				// 匿名巢狀Sender介面
	Reciver					
	Open() error			// 除匿名介面外的其他自定義函式
	Close() error
}

type MSNClient struct {
}

func (c MSNClient) Send(msg string) error {
	fmt.Println("send:", msg)
	return nil
}

func (c MSNClient) Reciver() (string, error) {
	fmt.Println("recive")
	return "", nil
}

func (c MSNClient) Open() error {
	fmt.Println("open")
	return nil
}

func (c MSNClient) Close() error {
	fmt.Println("error")
	return nil
}

func main() {
	msn := MSNClient{}			// 結構體初始化
	var s Sender = msn			// 結構體賦值給介面
	var r Reciver = msn
	var c Client = msn

	s.Send("1")			        // 介面呼叫結構體方法
	r.Reciver()
	c.Open()
	defer c.Close()
	c.Send("2")
	c.Reciver()

}

匿名介面

func (c MSNClient) Close() error {
	fmt.Println("error")
	return nil
}

type MSNClient struct {
}

main(){
    msn := MSNClient{}     // 結構體初始化
    
    var closer interface { // 定義匿名介面
		Close() error
	}
	closer = msn
	closer.Close()     // error 通過介面變數呼叫函式
}

空介面

在go中可以通過空介面 接收任意型別的變數

type EStruct struct {         // 定義空結構體
}

type Empty interface {        // 定義空介面
}

func main() {
	es := EStruct{}
	var e interface{} = 1 // 定義空介面為1
	fmt.Println(es, e)    // {} 1

	e = "test"
	fmt.Println(e)	      // test
	
	e = true
	fmt.Println(e)	      // true
}
  • 函式傳入介面型別,遍歷引數

type EStruct struct { // 定義空結構體
}



func fargs(args ...interface{}) {
	fmt.Println("----------------------------")
	for _, arg := range args {			// 傳入引數遍歷
		fmt.Println(arg)			// 列印傳入引數
		switch v := arg.(type) {		// 介面獨有的判斷型別方法
		case int:
			fmt.Printf("INT: %T %v\n", v, v)
		case string:
			fmt.Printf("String: %T %v\n", v, v)
		default:
			fmt.Printf("Other: %T %v\n", v, v)
		}
	}

}

func main() {
	es := EStruct{}
	
	fargs(1, "test", true, es)
}

序列化

序列化:將資料結構或物件轉換為二進位制串的過程

反序列化:在序列化過程中生成的二進位制串轉換為資料結構或者物件的過程

func main() {
	names := []string{"湯採玉", "湯文廣", "劉利純", "憨憨"}
    users := []map[string]string{{"name": "tcy", "add": "上海"}, {"name": "twg", "add": "長沙"}, {"name": "llc", "add": "長沙"}}

	// 序列化
	bytes, err := json.Marshal(names)
	if err == nil {
		fmt.Println(string(bytes))  // ["湯採玉","湯文廣","劉利純","憨憨"]
	}


	// 序列化
	bytes, err = json.Marshal(users)
	if err == nil {
		fmt.Println(string(bytes)) // [{"add":"上海","name":"tcy"},{"add":"長沙","name":"twg"},{"add":"長沙","name":"llc"}]
	}
    
}
  • 反序列化
	names := []string{"湯採玉", "湯文廣", "劉利純", "憨憨"}
	users := []map[string]string{{"name": "tcy", "add": "上海"}, {"name": "twg", "add": "長沙"}, {"name": "llc", "add": "長沙"}}

	// 序列化
	bytes, err := json.Marshal(names)
	if err == nil {
		fmt.Println(string(bytes)) // ["湯採玉","湯文廣","劉利純","憨憨"]
	}

	// 反序列化
	var names02 []string
	err = json.Unmarshal(bytes, &names02)
	fmt.Println(err)                   // <nil>
	fmt.Println(names02)               // [湯採玉 湯文廣 劉利純 憨憨]

	// 序列化
	bytes, err = json.Marshal(users)
	if err == nil {
		fmt.Println(string(bytes)) // [{"add":"上海","name":"tcy"},{"add":"長沙","name":"twg"},{"add":"長沙","name":"l
		//lc"}]
	}

	// 反序列化
	var user02 []map[string]string
	err = json.Unmarshal(bytes, &user02)
	fmt.Println(err)
	fmt.Println(user02)               // [map[add:上海 name:tcy] map[add:長沙 name:twg] map[add:長沙 name:llc]]

}
  • json格式化
names := []string{"湯採玉", "湯文廣", "劉利純", "憨憨"}

	// 序列化並格式化
	bytes, err := json.MarshalIndent(names, "", "\t")
	if err == nil {
		fmt.Println(string(bytes)) 
	}

/*
[
        "湯採玉",
        "湯文廣",
        "劉利純",
        "憨憨"
]

*/
  • json自動型別
type Size int

const (
	Large = iota
	Medium
	Small
)

func (s Size) MarshalText() ([]byte, error) {
	switch s {
	case Large:
		return []byte("large"), nil
	case Medium:
		return []byte("medium"), nil
	case Small:
		return []byte("small"), nil
	default:
		return []byte("unknow"), nil
	}
}

func (s *Size) UnmarshalText(bytes []byte) error {
	switch string(bytes) {
	case "large":
		*s = Large
	case "medium":
		*s = Medium
	case "Small":
		*s = Small
	}
	return nil
}

func main() {
	var size Size = Medium

	// 序列化
	bytes, _ := json.Marshal(size)
	fmt.Println(string(bytes))

	// 反序列化
	var size02 Size
	json.Unmarshal(bytes, &size02)
	fmt.Println(size02)

}
  • 結構體序列化
// 需要進行序列化或反序列化的屬性必須公開,也就是首字母大寫,否則無法序列化
// `json:"sex,int,omitempty"` 當屬性為0不進行序列化
type User struct {
	ID   int    `json:"-"`         // 屬性標籤json為名稱,- 為值,也表示忽略
	Name string `json:"name"`      // 改變屬性名,如防止屬性名衝突的情況
	sex  int                       // 小寫無法被json轉換
	Tel  int    `json:"id,string"` // 改變屬性型別,僅作用於json轉換
	Addr string
}

func main() {
	user := User{1, "kk", 1, 123, "西安"}

	// 序列化結構體
	bytes, _ := json.MarshalIndent(user, "", "\t")
	fmt.Println(string(bytes))

	// 反序列化結構體
	var user02 User
	json.Unmarshal(bytes, &user02)
	fmt.Println(user02)               // {0 kk 0 123 西安}

}

/*
{
        "name": "kk",
		 "Tel": "123",
        "Addr": "西安"
}

*/

反射

反射是指在運動時動態的訪問和修改任意型別物件的結構體和成員,在go語言中提供reflect包提供反射的功能,每一個變數都有兩個屬性,型別和值

reflect.Type是一個介面型別,用於獲取變數型別的資訊,可以通過reflectTypeOf函式獲取某個變數型別資訊:

1> 通用方法

​ Name(): 型別名

​ PkgPath(): 包路徑

​ String(): Type字串

​ Kind(): 型別列舉值

​ Comparable(): 是否可進行比較

​ Implements(): 是否實現某介面

​ AssignableTo(Type): 是否可賦值給某型別

​ ConvertibleTo(Type): 是否可轉換為某型別

​ NumMethod(): 方法個數

​ Method(int): 通過索引獲取方法型別

​ Method結構體常用屬性:

​ Name: 方法名

​ Type: 函式型別

​ Func:方法值(Value)

​ MethodByName(string): 通過方法名字獲取方法型別

  • 結構體 reflect.Struct

NumField:屬性個數

Field(int):通過索引獲取屬性

​ StructField結構體常用屬性

​ Name:屬性名

​ Anonymous:是否為匿名

​ Tag標籤:

​ StructTag常用方法:

​ Get(string)

​ Lookup(string)

FieldByName(string): 通過屬性名獲取屬性

  • 結構體型別 reflect.Value

reflect.Value是一個結構體型別,用於獲取變數值的資訊,可以通過reflect.ValueOf函式獲取某個變數值資訊

1> 建立方法

2> 通用方法

  • Type(): 獲取值型別
  • CanAdd(): 是否可獲取地址
  • Addr(): 獲取地址
  • Caninterface(): 是否可獲取介面的
  • InterfaceData():
  • Interface(): 將變數轉換為interface{}
  • CanSet(): 是否可更新
  • isVaild(): 是否初始化為零值
  • Kind(): 獲取值型別列舉值
  • NumMethod(): 方法個數
  • Method(int): 通過索引獲取方法值
  • MethodByName(string): 通過方法名字獲取方法值
  • Convert(Type): 轉換為對應型別的值

3> 呼叫方法:

  • Call
  • CalSlice

4> 修改方法

  • Set/Set*: 設定變數值

5> 特定型別方法

a) reflect.Int,reflect.Unit,

  • int(): 獲取對應型別值
  • Unit(): 獲取對應型別值

b)reflect.Float*

  • Float(): 獲取對應型別值

c)reflect.Complex*

  • Complex(): 獲取對應型別值

d) reflact.Arry

  • Len(): 獲取陣列長度
  • Index(int): 根據索引獲取元素
  • Slice(int,int): 獲取切片
  • Slice(int,int,int): 獲取切片

e) reflact.Slice

  • IsNil():
  • Len():獲取元素數量
  • Cap(): 獲取容量
  • 根據變數,獲取型別方法
func main() {
	var i int = 1
	fmt.Printf("%T\n", i) // 底層使用反射查詢出對應型別你

	var typ reflect.Type = reflect.TypeOf(i) // 實現反射底層,查詢型別
	fmt.Println(typ)
}