当前位置:网站首页>Recognize function originality

Recognize function originality

2022-06-12 17:38:00 Erya preaches Buddhism

Functions form the logical structure of code execution . stay Go In language , The basic composition of a function is : keyword func, Function name , parameter list , Return value , Function bodies and return statements .

Go The language function definition format is as follows :

func FuncName(/* parameter list */) (01 type1, 02 type2/* Return type */) {
	// The body of the function 
	return v1, v2 // Return multiple values 
}

Function definition description :

  • func: Functions have keywords func Statement .
  • FuncName: The name of the function , According to the contract , Function names start with lowercase letters private, Capitalized means public.
  • parameter list : Functions can have 0 One or more parameter lists , The parameter format is : Variable name type , If you have more than one parameter , Separated by commas , Default parameters... Are not supported
  • Return type :
  • The above return value declares two variable names 01 and 02( Command return parameters ), This is not necessary , You can only type without variable name .
  • If there is only one return value and the return value variable is not declared , Then you can omit , Include returned parentheses .
  • If there is no return value , Then omit the last return information directly .
  • If there is a return value , So you have to add... Inside the function return sentence .

1, No parameter, no return value .

package main

import "fmt"

// Definition of function with no parameter and no return value 
func MyFunc() {
	a := 666
	fmt.Println("a =", a)
}

// It is the same to place the called function above or below , The program from main Function into , And then call MyFunc End of the function .

func main() {
	// A call to a function that has no parameters and no return value : Function name ()
	MyFunc()
}

2, Return value with parameter or not .

1, Common parameter list .

package main

import "fmt"

/*
 Definition of function with parameter and no return value , Common parameter list 
 When defining a function , After the function name () The parameters defined are called formal parameters 
 Parameter passing , Only arguments can be passed to formal parameters , It can't be reversed , This is a single pass 
*/

func MyFunc01(a int) {
	fmt.Println("a =", a)
}

func MyFunc02(a int, b int) {
	fmt.Printf("a = %d, b = %d\n", a, b)
}

// Or written 
func MyFunc03(a, b int) {
	fmt.Printf("a = %d, b = %d\n", a, b)
}

func MyFunc04(a int, b string, c float64) {
}

func MyFunc05(a, b string, c float64, d, e int) {

}

// The following is recommended , It is clear and easy to recognize .
func MyFunc06(a string, b string, c float64, d int, e int) {

}

func main() {
	// Function call mode with parameters and no return value :  Function name ( Required parameters )
	// The parameters passed by the function are called arguments 
	MyFunc01(666)
	MyFunc02(666, 777)
}

2, Indefinite parameter type .

package main

import "fmt"

// As previously defined , Are all normal parameters , Or fixed parameters , Examples are as follows :
func MyFunc01(a int, b int) {

}

// Next is the indefinite parameter type 
//...int  Types like this , Is an indefinite parameter type 
// Be careful : Uncertain parameters , A certain ( Can only ) Is the last parameter in the formal parameter 
func MyFunc02(args ...int) { // The parameters passed can be 0 One or more 
	fmt.Printf("len(args) = %d\n", len(args)) // Indicates the number of parameters passed by the user 

	// How to print the parameters entered by the user , Can pass for Loop to execute 
	// for i := 0; i < len(args); i++ {
	// 	fmt.Printf("args[%d] = %d\n", i, args[i])
	// }
	// Or use range Print , The code is as follows 
	for i, date := range args { // Represents traversal parameter list 
		fmt.Printf("args[%d] = %d\n", i, date)
	}
}

// func MyFunc03(a int,b int, test ...int){
// 	// This is the correct demonstration 
// }

// func MyFunc04(a int, test ... int, b int){
// 	// This is a false demonstration , Whether it's in the middle , Or at the beginning , It's not allowed 
// }

func main() {
	MyFunc02()
	MyFunc02(1)
	MyFunc02(1, 2, 3)
}

3, The transfer of indefinite parameters .

package main

import "fmt"

/*
1, First, four values are passed to the main function test Indefinite arguments in a function args.
*/
func myfunc(tmp ...int) {
	for _, date := range tmp {
		fmt.Printf("date = %d\n", date)
	}
}

func test(args ...int) {
	// If you pass all the elements to myfunc, It can be done as follows 
	//myfunc(args...)

	// Just want to pass some two elements down , How to write 
	myfunc(args[2:]...) // Express the args[0]~args[2]( barring args[2]) The corresponding element is passed to the past 
	myfunc(args[:2]...) // From args[2]( Include args[2] In itself ) Start , The back ones are passed on 
}

func main() {
	test(1, 2, 3, 4)
}

3, No parameter return value .

1, Single return value .

package main

import "fmt"

// No parameter return value , An example of a return value 
// Functions with return values need to pass return Keyword interrupt function , adopt return return 
func myfunc() int {
	return 666
}

func MyFunc01() (test int) {
	return 777
}

// Define a name for the return value test The variable of , Then assign values to variables , then return get out , yes go Recommend writing , This kind of writing is more commonly used 
func MyFunc02() (test int) {
	test = 888
	return
}

func main() {
	// Standard writing 
	var a int
	a = myfunc()
	fmt.Println("a =", a)
	// You can also use the method of automatically pushing to type 
	b := myfunc()
	fmt.Println("b =", b)

	c := MyFunc01()
	fmt.Println("c =", c)

	d := MyFunc02()
	fmt.Println("d =", d)
}

2, Multiple return values .

package main

import "fmt"

func MyFunc01() (int, int, int) {
	return 1, 2, 3

}

// Commonly used writing 
func MyFunc02() (a, b, c int) {
	a, b, c = 4, 5, 6
	return
}

func main() {
	a, b, c := MyFunc02()
	fmt.Printf("a = %d,b = %d, c = %d\n", a, b, c)
}

4, With parameter and return value .

package main

import "fmt"

// Function definition 
func MaxAndMin(a, b int) (max, min int) {
	if a > b {
		max = a
		min = b
	} else {
		max = b
		min = a
	}
	return // Function with return value , Must pass return Keywords return 
}

func main() {
	// Function call .
	max, min := MaxAndMin(10, 20)
	fmt.Printf("max = %d, min = %d\n", max, min)

	// Discarding a value through an anonymous variable 
	a, _ := MaxAndMin(5, 2)
	fmt.Println("a =", a)
}

5, Normal function call process .

In functions , The sequence of program execution is , First call , After the return .

package main

import "fmt"

func funcc(c int) {
	fmt.Println("c =", c)
}

func funcb(b int) {
	funcc(b - 1)
	fmt.Println("b =", b)
}

func funca(a int) {
	funcb(a - 1)
	fmt.Println("a =", a)
}

func main() {
	funca(3)
	fmt.Println("main")
}

Maybe the function is not easy to see , Then you can draw pictures to analyze them one by one :

6, Recursive function call process .

1, Know recursive functions .

Recursive function means that a function can call itself directly or indirectly .

Recursive functions usually have the same structure : A jump condition and a recursive body . The so-called jump condition is to judge whether to terminate the recursion according to the passed parameters , The recursive body is the function itself to do some processing .

package main

import "fmt"

// recursive , It is to call itself in the process of operation. 
func test(a int) {
	// Exit conditions must be set , Otherwise, it will enter an infinite loop 
	if a == 1 {
		fmt.Println("a =", a)
		return // Terminate function call 
	}
	// Function call itself 
	test(a - 1)
	fmt.Println("a =", a)
}

func main() {
	test(3)
	fmt.Println("main")
}

Analyze the running process by drawing a diagram .

Use words to describe the execution process in detail , Note that the text is slightly simpler than the steps of drawing , It's actually a combination of some steps .

  • 1, adopt main The entry function enters the program .
  • 2, Call function test, And assign the variable a by 3.
  • 3, The program comes to the function test, here a=3, Does not meet the judgment conditions , So go down , Call function test, And assign the variable a by (a-1), In fact, that is 3-1
  • 4, The program comes to the function again test, here a=2, Does not meet the judgment conditions , So go down , Call function test, And assign the variable a by (a-1), In fact, that is 2-1
  • 5, The program comes to the function again test, here a=1, Meet the judgment conditions , So go into judgment , Print at this time a Value , by 1, then return Jump out of .
  • 6, After jumping out , The function returns to the 4 Step , Then print this time a Value , by 2, Complete this operation , Jump out of .
  • 7, After jumping out , The function returns to the 3 Step , Then print this time a Value , by 3, Complete this operation , Jump out of .
  • 8, After jumping out , The function returns to the 2 Step , Then print a string main.

Among them, for article 6,7 Two steps , A simple analysis is as follows :

The front one 5 Step , It's easy to understand , But come to No 6 Step , I feel a little dizzy , I don't know why I still go back to print , Then I turned it up again , Let's take a look at the above example of ordinary function calls , Just a little bit , In fact, to the third 6 Step ( That is, the completion of step 5 ), It is equivalent to that the program has completed the 4 Step function call , Combine to call first , The theory of post - return , At this point, the call ends , It's time to print . Empathy , To the first 7 Step ( That is the first. 6 Step completion ), It is equivalent to that the program has completed the 3 Step function call , When it's done , Print the value at that time , Then push back in the same way , Until the program completes the final logical planning .

2, Calculate the sum of the numbers .

Yesterday , Have used for Loop to achieve , Now you can stop looking back at the document , Do it yourself for The cumulative sum of cycles .

package main

import "fmt"

func main() {
	sum := 0
	for i := 1; i <= 100; i++ {
		sum = sum + i
	}
	fmt.Println("1 Add to 100 And is :", sum)
}

Now to understand , Probably not very difficult , This is calculated from 1 Add to 100 And , You can also write from 100 Add to 1 And , as follows :

package main

import "fmt"

func main() {
	sum := 0
	for i := 100; i >= 1; i-- {
		sum = sum + i
	}
	fmt.Println("100 Add to 1 And is :", sum)
}

that , Now you should be able to try using recursive functions to implement it , Or from the 1 Add to 100 Start .

package main

import "fmt"

func test(i int) int {
	if i == 100 {
		return 100
	}
	return i + test(i+1)
}

func main() {
	var sum int
	sum = test(1)
	fmt.Println("1 Add to 100 And is :", sum)
}

Without the aid of drawing , Let's first read the process executed by the function .

1, adopt main The entry function enters the program .

2, Define a variable sum, Let it be equal to a function test(), And passing parameters makes i=1.

3, Come to the function test in , here i=1, First and then enter if Judge , Obviously it doesn't mean 100, Then down , obtain i+test(i+1), It's actually 1+test(1+1), here 1 Retain , The back test(1+1) Enter the function again .

4, Come to the function again test in , here i=2, First and then enter if Judge , Obviously it doesn't mean 100, Then down , obtain i+test(i+1), It's actually 2+test(2+1), here 2 Retain , The back test(2+1) Enter the function again .

5, Come to the function again test in , here i=3, First and then enter if Judge , Obviously it doesn't mean 100, Then down , obtain i+test(i+1), It's actually 3+test(3+1), here 3 Retain , The back test(3+1) Enter the function again .

6, Come to the function again test in , here i=4, First and then enter if Judge , Obviously it doesn't mean 100, Then down , obtain i+test(i+1), It's actually 4+test(4+1), here 4 Retain , The back test(4+1) Enter the function again . ...... Such a cycle 99 Time , Until the last time .

7, Come to the function again test in , here i=100, First and then enter if Judge , be equal to 100, then return One 100, And so many times before , Has accumulated to 1+2+3...+99, Plus this 100, It is the final result .

Then try again from 100 Add to 1 Summation of .

package main

import "fmt"

func test01(i int) int {
	if i == 1 {
		return 1
	}
	return i + test01(i-1)
}

func main() {
	var sum int
	sum = test01(100)
	fmt.Println("100 Add to 1 And is :", sum)
}

This addition procedure and call , It is basically consistent with the above .

7, Function type .

1, Recognize function types .

stay go In language , Function is also a data type , It can be used type To define it , Its type is the same parameter it has , A type of the same return value .

package main

import "fmt"

// Addition of two numbers 
func Add(a, b int) int {
	return a + b
}

// Subtraction of two numbers 
func Minus(a, b int) int {
	return a - b
}

// Function is also a data type , adopt type You can give the function a name , Then call the function by this name .
//FuncType Is a function type 
type FuncType func(int, int) int // No function name , No, {}

func main() {
	// Call functions in the traditional way 
	var result int
	result = Add(8, 5)
	fmt.Println("result =", result)

	// Now call by the function type name just defined 
	var ftest FuncType     // Define a variable ftest, Its type is just defined FuncType
	ftest = Add            // You can then assign the function name to the variable ftest, So that ftest Function capability with corresponding name 
	result = ftest(10, 20) // Equivalent to  restult = Add(10,20)
	fmt.Println("result1 =", result)

	// Again , You can also assign another function name to a variable .
	ftest = Minus
	result = ftest(1, 1) // Equivalent to  restult = Minus(1,1)
	fmt.Println("result2 =", result)
}

The above is an example of a traditional definition and invocation , You can also use the following method to define and call .

package main

import "fmt"

type FuncType func(int, int) int // Declare a function type 

// A parameter type in the function is function type :f FuncType
func Calc(a, b int, f FuncType) (result int) {
	result = f(a, b)
	return
}

func Add(a, b int) int {
	return a + b
}

func main() {
	// Function call , The third parameter is the function name , Parameters for this function , The return value must be the same as FuncType The same type 
	a := Calc(3, 3, Add)
	fmt.Println("a=", a)
}

So this function type , What's the use of it , Isn't it easier to call directly . Next , You can see its function .

2, polymorphic .

Function types can be applied to polymorphism , Before moving on to the formal example , Let's first look at a common addition code .

package main

import "fmt"

// Addition of two numbers 
func Add(a, b int) int {
	return a + b
}
// The main program function calls the addition function 
func Calc(a, b int) (result int) {
	fmt.Println("Calc")
	result = Add(a, b)
	return
}

func main() {
	a := Calc(3, 3)
	fmt.Println("a=", a)
}

Then let's look at another way of writing :

package main

import "fmt"

type FuncType func(int, int) int

// Addition of two numbers 
func Add(a, b int) int {
	return a + b
}

// Subtraction of two numbers 
func Minus(a, b int) int {
	return a - b
}

// Multiply two numbers 
func Mul(a, b int) int {
	return a * b
}

/*
 Calculator , Four operations can be performed 
 Callback function , A function has an argument of function type , This function is the callback function . In the example below , Parameters ftest The type of is the function type defined above (FuncType)
 polymorphic , In many forms , Call the same interface , Different performance , Different results can be achieved .
*/

func Calc(a, b int, ftest FuncType) (result int) {
	fmt.Println("Calc")
	result = ftest(a, b)
	return
}

func main() {
	a := Calc(3, 3, Mul)
	fmt.Println("a=", a)
}

Briefly explain .

I didn't quite understand it at first , But I practiced a few examples , I found some of the mysteries . from main The definition of entrance begins to understand ,Calc(3, 3, Mul) Over the function , Pay attention to the Mul, Equate to ftest The location of , So after the replacement , You will find , And the addition example just written above , It's basically the same .

8, Anonymous functions and closures .

Closure is a function “ Capture ” Other constants and variables in the same scope as it . This means that when a closure is called , No matter where the program is called , Closures can use these constants or variables . It doesn't care if these captured variables and constants are out of scope , So only closures use it , These variables will still exist .

stay Go In language , All anonymous functions (Go In the language specification, it is called function digital surface quantity ) All are closures. . Anonymous function is a function implementation that does not need to define a function name .

1, Know anonymous functions and closures .

package main

import "fmt"

func main() {
	a := 10
	str := "mike"

	// Anonymous functions , No function name , The following is just the definition of the function 
	f1 := func() { // Automatic derivation type , Assign an anonymous function operation to f1
		fmt.Printf("a =%d, str =%s\n", a, str)
	}
	f1() // Use this method to make calls .

	// Alias an anonymous function type , This kind of writing is not often used .
	type FuncType func() // Function has no arguments , no return value 
	var f2 FuncType
	f2 = f1
	f2()

	// Define anonymous functions and call 
	func() {
		fmt.Printf("a =%d, str =%s\n", a, str)
	}() // hinder () Means to call this anonymous function 

	// Anonymous functions with parameters 
	f3 := func(i, j int) {
		fmt.Printf("i =%d, j =%d\n", i, j)
	}
	f3(3, 5)
	// Another way of writing 
	func(i, j int) {
		fmt.Printf("i =%d, j =%d\n", i, j)
	}(5, 3)

	// Anonymous functions , With parameter and return value 
	x, y := func(i, j int) (max, min int) {
		if i > j {
			max = i
			min = j
		} else {
			max = j
			min = i
		}
		return
	}(6, 8)
	fmt.Printf("x = %d, y = %d\n", x, y)
}

2, Closures capture the characteristics of external variables .

package main

import "fmt"

func main() {
	a := 10
	str := "mike"
	func() {
		// Closures capture external variables by reference 
		a = 666
		str = "go"
		fmt.Printf("a = %d, str = %s\n", a, str)
	}()

	fmt.Printf("a = %d, str = %s\n", a, str)
}

Results output :

a = 666, str = go
a = 666, str = go

Equivalent to in anonymous function , Changed the value of the variable , Then go outside the anonymous function , The value also changes .

To verify this feature , Now you can make a comparison .

First look at the situation through a common function type :

package main

import "fmt"

func test01() int {
	var a int // When a variable is not initialized , The default is 0
	a++
	return a * a	// Function call completed ,a Automatic release .
}
func main() {
	fmt.Println(test01())
	fmt.Println(test01())
	fmt.Println(test01())
	fmt.Println(test01())
	fmt.Println(test01())
}

The output is :

$ go run 15_ Characteristics of closures .go

1
1
1
1
1

Pay attention to the above sentence , Call complete , The value of the variable is automatically released , To get the above results .

Let's look at another example :

package main

import "fmt"
// The return value of the function is an anonymous function , Returns a function type 
func test02() func() int {
	var a int // When a variable is not initialized , The default is 0
	return func() int {
		a++
		return a * a
	}
}
func main() {
	// The upper return value is an anonymous function , Returns a function type , So here's a variable f To call the returned anonymous function ( Closure function )
	// here , It doesn't care if the captured variables or constants are out of scope , As long as the closure is still in use , These variables will always exist .
	f := test02()
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
	fmt.Println(f())
}

Output results :

$ go run 15_ Characteristics of closures .go

1
4
9
16
25

At the same time, pay attention to the above words , Every time a closure is called , Then the last value will be saved , As the results show , Every time you call ,a The initial values of are all the new values obtained after the last closure .

9, Delay the call defer.

1, understand defer.

keyword defer Used to delay a function or method ( Or the currently created anonymous function ) Implementation , Delay until the end of the function . Be careful ,defer Statements can only appear inside functions or methods .

package main

import "fmt"

func main() {
	//defer Delay call , It means that main Call... Before the function ends , That is to say, it should be executed at the end 
	defer fmt.Println("aaaaaaa")
	fmt.Println("bbbbbbb")
}

defer Statements are often used to handle pairs of operations , Like opening 、 close , Connect 、 disconnect , Lock 、 Release the lock ,, etc. , adopt defer, No matter how complex the function logic is , Under any execution path , Resources released , Release resources defer sentence , It should be directly followed by the statement requesting the resource .

2, Multiple defer Execution order of .

If there are more than one function defer sentence , They will use First in, then out ( Which is defined first , After execution ) Sequential execution , Even if a function or a deferred call will have an error , These calls will still be executed .

package main

import "fmt"

func test(x int) {
	fmt.Println(100 / x) //x by 0 when , Cause abnormal 
}

func main() {

	defer fmt.Println("aaaaaaa")
	defer fmt.Println("bbbbbbb")
	defer test(0)
	defer fmt.Println("ccccccc")
}

give the result as follows :

$ go run 17_ Multiple defer Execution order .go

ccccccc
bbbbbbb
aaaaaaa
panic: runtime error: integer divide by zero

goroutine 1 [running]:
main.test(0x0)
        C:/Users/Administrator/Desktop/gocode/src/day2/17_ Multiple defer Execution order .go:6 +0xa9
main.main()
        C:/Users/Administrator/Desktop/gocode/src/day2/17_ Multiple defer Execution order .go:15 +0x15e
exit status 2

3,defer Use with anonymous functions .

Let's start with an example without parameters .

package main

import "fmt"

func main() {
	a := 10
	b := 20
	defer func() {
		fmt.Printf("a = %d, b = %d\n", a, b)
	}()

	a = 100
	b = 200
	fmt.Printf(" external :a = %d, b = %d\n", a, b)
}

Results output :

$ go run 18_defer Use with anonymous functions .go

 external :a = 100, b = 200
a = 100, b = 200

Then define two parameters for the anonymous function , Look at the results .

package main

import "fmt"

func main() {
	a, b := 10, 20
	defer func(a, b int) {
		fmt.Printf("a = %d, b = %d\n", a, b)
	}(a, b)  // Function execution time , arrive defer Statement place , Although it will not be implemented for the time being , But the parameters have been passed , Results to the final output .

	a = 100
	b = 200
	fmt.Printf(" external :a = %d, b = %d\n", a, b)
}

Results output :

$ go run 18_defer Use with anonymous functions .go

 external :a = 100, b = 200
a = 10, b = 20

10, Get command line parameters .

package main

import (
	"fmt"
	"os"
)

func main() {
	list := os.Args
	n := len(list)
	fmt.Println(" The number of parameters is :", n)
}

Take a look at it :

$ go run 19_ Get command line parameters .go 1 2 3
 The number of parameters is : 4

You can print these parameters separately :

package main

import (
	"fmt"
	"os"
)

func main() {
	list := os.Args
	n := len(list)
	fmt.Println(" The number of parameters is :", n)

	for i := 0; i < n; i++ {
		fmt.Printf("list[%d] = %s\n", i, list[i])
	}
	// Iterative printing 
	for i, data := range list {
		fmt.Printf("list[%d] = %s\n", i, data)
	}
}

Running results :

$ go build 19_ Get command line parameters .go

$ ./19_ Get command line parameters .exe 1 2 3

 The number of parameters is : 4
list[0] = C:\Users\Administrator\Desktop\gocode\src\day2\19_ Get command line parameters .exe
list[1] = 1
list[2] = 2
list[3] = 3
list[0] = C:\Users\Administrator\Desktop\gocode\src\day2\19_ Get command line parameters .exe
list[1] = 1
list[2] = 2
list[3] = 3

11, Scope .

1, local variable .

package main

import "fmt"

func test() {
	a := 10
	fmt.Println("a =", a)
}

/*
 Scope : Is the range in which the variable works .
 It's defined in {} The variables inside are local variables , At the same time, it is only in {} It works inside .
 Execute to the sentence of defining variables , To allocate space to variables , Automatically release after leaving the scope 
*/

func main() {
	fmt.Println("a =", a)

	{
		i := 10
		fmt.Println("i = ", i)
	}
	fmt.Println("i = ", i)
	if b := 3; b == 3 {
		fmt.Println("b = ", b)
	}
	fmt.Println("b = ", b)
}

2, Global variables .

package main

import "fmt"

// A global variable is a quantity defined outside a function 
// Global variables can be used anywhere 

var a int

func main() {
	a = 10
	fmt.Println("a =", a)
	test()
}

func test() {
	fmt.Println("test a =", a)
}

3, Variables with the same name in different scopes .

package main

import "fmt"

var a byte // Global variables 
//1, Different scope , Variables with the same name are allowed to be defined 
//2, Principles of using variables , Nearby principle .

func main() {
	var a int // local variable 
	fmt.Printf("1: %T\n", a)

	{
		var a float64
		fmt.Printf("2: %T\n", a)
	}
	test()
}

func test() {
	fmt.Printf("3: %T\n", a)
}

12, Variable parameters

// Variable parameters 
func add(a...int) int {	//0 One or more variable parameters 

}

func add(a int, arg...int) int { //1 One or more variable parameters 

}

func add(a, b int, arg...int) int { //2 One or more variable parameters 

}
// Be careful : among arg It's a slice, It can be done by arg[index] To get the corresponding parameters , adopt len(arg) To determine the number of parameters 

Application of variable parameters :

package main

import "fmt"

//  Variable parameter of function 

func f(a ...interface{}) {
	// a  It's a slice 
	fmt.Printf("type:%T  value:%#v\n", a, a)
}
func main() {
	var s = []interface{}{1, 3, 5, 7, 9}
	f(s)    //  Express the s This slice is taken as a whole , As a function parameter a The first element of this slice 
	f(s...) // Express the s Data expansion in this slice , As function arguments one by one a The elements of this slice 
}

The above code outputs the result :

type:[]interface {}  value:[]interface {}{[]interface {}{1, 3, 5, 7, 9}}
type:[]interface {}  value:[]interface {}{1, 3, 5, 7, 9}
原网站

版权声明
本文为[Erya preaches Buddhism]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/163/202206121731439272.html