Why is there a function?
At first glance, this problem is a bit SB. The function must be written for use, but can't I implement my steps step by step to realize the function? Yes, but on the one hand, it will cause code redundancy and heavy workload. On the other hand, it is unsightly and concise. In my opinion, function is to extract the functions that often need to be used and package them into a function for subsequent repeated calls. It reflects a characteristic: reusability.
What is the method?
When it comes to methods, we have to mention the struct structure in Go language. The struct structure is actually an object, and the method is actually a function bound to a struct. Analogy Python is the function encapsulated in the class class. The actual application is that after you instantiate a struct, you can use all the methods bound to struct. My understanding is that the function is further refined according to the object struct. This part of the function is called method.
Interface?
A: You've been writing Go for two days. Should you write a lot of interfaces?
B: Interface?
Interface interface is also an object. I didn't understand this before. Recently, I suddenly understand this thing. Interface is also an object, but this object is not a very visualized object like struct structure. It is an abstract object. I mentioned the method above. Different structs can also have similar functions. For example, computers and mobile phones can realize the function of surfing the Internet. The premise is: 1 Electricity 2 Network communication. Public functions (Internet access) can be encapsulated into an interface, and the instance implementing this interface can call the method under this interface. In fact, it is to further refine the previous method. The interface type variable can store all instances that implement the interface.
type tester interface{ method1(Enter reference)(return) method2(Enter reference)(return) } type struct1 struct{} type struct2 struct{} func(s1 *struct1) method1(Enter reference)(return){} func(s2 *struct2) method1(Enter reference)(return){} func(s1 *struct1) method2(Enter reference)(return){} func(s2 *struct2) method2(Enter reference)(return){} func main(){ var x tester s1 := struct1{} //instantiation s2 := struct1{} //instantiation x = &s1 x.method1(Enter reference) x.method2(Enter reference) x = &s2 x.method1(Enter reference) x.method2(Enter reference)
summary
Reusable functions can be encapsulated by functions. Some objects have functions. You can bind struct to generate method by function. Some objects have the same functions (functions), which can be refined to generate interface. In short: continuous refining, summary and classification!
Attachment:
GO realizes ssh Remote Operation on the server: 1 Connection 2 Execute command 3 View directory file list 4 Upload and download files
common
package common import ( "bytes" "fmt" "github.com/pkg/sftp" "golang.org/x/crypto/ssh" "log" "net" "os" "path" "path/filepath" ) type HostConn struct { IP string User string Password string Port int } func (hc *HostConn) SSHConn() (*ssh.Client, error) { var ( auth []ssh.AuthMethod addr string clientConfig *ssh.ClientConfig client *ssh.Client //session *ssh.Session err error ) auth = make([]ssh.AuthMethod, 0) auth = append(auth, ssh.Password(hc.Password)) hostKeyCallback := func(hostname string, remote net.Addr, key ssh.PublicKey) error { return nil } clientConfig = &ssh.ClientConfig{User: hc.User, Auth: auth, HostKeyCallback: hostKeyCallback} // create ssh addr = fmt.Sprintf("%s:%d", hc.IP, hc.Port) client, err = ssh.Dial("tcp", addr, clientConfig) if err != nil { return nil, err } // create session //if session, err = client.NewSession(); err != nil { // return nil, err //} return client, err } func (hc *HostConn) RemoteCMD(cmd string) { var ( stdOut bytes.Buffer stdErr bytes.Buffer ) client, err := hc.SSHConn() if err != nil { fmt.Printf("ssh tcp connect failed,err:%v\n", err) return } session, err := client.NewSession() if err != nil { fmt.Printf("cmd session create failed,err:%v\n", err) return } defer session.Close() session.Stdout = &stdOut session.Stderr = &stdErr err = session.Run(cmd) if err != nil { fmt.Printf("ssh cmd execute failed,err:%v\n", err) return } fmt.Printf("The standard output is:%s", stdOut.String()) fmt.Printf("The standard error is:%s", stdErr.String()) } func (hc *HostConn) SftpFileList(remotePath string) (s []string) { client, err := hc.SSHConn() if err != nil { fmt.Printf("sftpfilelist create client failed,err:%v\n", err) return nil } defer client.Close() sftpClient, err := sftp.NewClient(client) if err != nil { fmt.Printf("sftpfilelist create sftp client failed,err:%v\n", err) return nil } w := sftpClient.Walk(remotePath) for w.Step() { if w.Err() != nil { continue } if !w.Stat().IsDir() { a := path.Dir(w.Path()) if a != remotePath { continue } s = append(s, w.Path()) } } return s } func (hc *HostConn) SftpDownLoad(localPath, remotePath string) { client, err := hc.SSHConn() if err != nil { fmt.Printf("ssh tcp connect failed,err:%v\n", err) return } sftpClient, err := sftp.NewClient(client) if err != nil { fmt.Printf("sftp client create failed,err:%v\n", err) return } s := hc.SftpFileList(remotePath) for _, k := range s { filename := path.Base(k) fmt.Println(filename) localFile := filepath.Join(localPath, filename) remoteFile := path.Join(remotePath, filename) fmt.Println(localFile) fmt.Println(remoteFile) dsFile, err := os.Create(localFile) if err != nil { fmt.Printf("create local file failed,err:%v\n", err) return } srcFile, err := sftpClient.Open(remoteFile) if err != nil { fmt.Printf("remote download file open remotefile failed,err:%v\n", err) return } // defer func() { // _ = dsFile.Close() // _ = srcFile.Close() // }() _, err = srcFile.WriteTo(dsFile) if err != nil { fmt.Printf("data write failed,err:%v\n", err) return } } fmt.Println("File download complete!") } func (hc *HostConn) SftpUpload(localFilePath, localFileName, remoteFilePath, remoteFileName string) { client, err := hc.SSHConn() if err != nil { log.Fatal(err) return } defer client.Close() SftpClient, err := sftp.NewClient(client) if err != nil { fmt.Printf("sftp client create failed,err:%v\n", err) return } // 1. Open local file // 2. Create a server-side file // 3. Read local file contents // 4. Write the read content to the remote server file localFile := filepath.Join(localFilePath, localFileName) remoteFile := path.Join(remoteFilePath, remoteFileName) fmt.Println(localFile, "\n", remoteFile) srcFile, err := os.Open(localFile) if err != nil { fmt.Printf("local file open failed,err:%v\n", err) return } defer srcFile.Close() dsFile, err := SftpClient.Create(remoteFile) if err != nil { fmt.Printf("create server file failed,err:%v\n", err) panic(err) } defer dsFile.Close() buf := make([]byte, 1024) for { n, _ := srcFile.Read(buf) // Write binary contents of the file to buf if n == 0 { break } dsFile.Write(buf) } fmt.Println("File upload completed!") } type Operator interface { SSHConn() (*ssh.Client, error) SftpDownLoad(localPath, remotePath string) SftpUpload(localFilePath, localFileName, remoteFilePath, remoteFileName string) SftpFileList(remotePath string) (s []string) RemoteCMD(cmd string) }
main.go
package main import ( "RemoteAction/common" "fmt" ) func main() { var x common.Operator hostConn := common.HostConn{ User: "xxx", IP: "xxxxx", Password: "xxxxx", Port: 22, } x = &hostConn List := x.SftpFileList("/xxx/xx/xxx") for _, k := range List { fmt.Println(k) } x.SftpDownLoad("C:\\Users\\Administrator\\Desktop\\test", "/xx/xxxx/xxxx") x.RemoteCMD("pwd") x.SftpUpload("C:\\Users\\Administrator\\Desktop\\test", "xxx.txt", "/home/tidb/scripts", "test.txt") }