Relationship among functions, methods and interfaces in Go language

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

Keywords: Go Back-end

Added by WebGeek182 on Tue, 01 Mar 2022 08:28:55 +0200