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)
}