Golang "일등 시민"- 함수 (function)

Golang 일등 시민 - 함수(function)

  • 첫째, 무엇이 일등 공민(first Class)인가 함수
  • 2. 성명 함수: 일반 함수는 반드시 먼저 성명해야 호출할 수 있다
  • 3. 호출 함수: 코드 간의 회전
  • 넷째, 매개 변수 전달 - Golang의 모든 매개 변수는 값 전달
  • 다섯째, 함수 변수 - 함수를 값으로 변수에 저장
  • 6. 익명 함수 - 이름이 없는 일반 함수
  • 익명 함수 성명, 호출
  • 익명 함수 리셋 함수 실현
  • 익명 함수 구현 조작 봉인
  • 1. "일등 공민(first Class)" 함수

  • 함수는 현재 주류인 C/C++, Java와 차이가 있는 값을 반환할 수 있습니다.
  • 함수 자체가 값으로 전달될 수 있음
  • 함수는 변수의 값으로 사용할 수 있다
  • 함수는 매개 변수와 반환값으로 사용할 수 있다
  • 익명 함수 (이름이 없는 함수) 는 일반적으로 공장 모드에 사용됩니다.
  • 인터페이스를 만족시킬 수 있다.함수는 반복적으로 사용할 수 있고 단일하거나 관련된 코드 부분을 실현하는데 그 목적은 모듈화 프로그래밍으로 모듈성과 코드의 복용률을 높이는 것이다.

  • 2. 성명 함수: 일반 함수는 반드시 먼저 성명해야 호출할 수 있다


    일반 함수 선언 규칙
  • 컴파일러는 성명을 통해 함수가 코드와 함수체 간의 상호작용을 어떻게 호출해야 하는지 알 수 있다(생산지 파라미터, 반환 파라미터)
  • 함수 이름: 첫 번째 자모는 숫자가 아닌 자모, 밑줄, 숫자로 구성된다.
  • 함수 이름은 같은 패키지(같은 폴더 아래)에서 이름을 바꿀 수 없습니다.
  • 매개변수 목록에 있는 변수는 로컬 변수로 존재합니다.
  • 함수는 반환 값이 있음을 설명할 때 함수체에return 문장을 사용하여 반환 값 목록을 제공해야 한다.
  • 매개변수 목록에 있습니다.쉼표로 구분되는 여러 매개변수 변수
  • 명명된 반환값 변수의 기본값은 형식의 기본값입니다. 즉, 값은 0이고, 문자열은 빈 문자열이며, 부울값은false이며, 인용은nil입니다.

  • 함수 기본 구조 형식:func 함수 이름 (인자 목록) (반환값 목록) {함수체}

    3. 호출 함수: 코드 사이의 이동


    함수는 정의된 후에 호출된 방식을 통해 현재 코드를 호출된 함수로 옮겨 실행합니다.호출된 함수 (호출 전 함수) 국부 변수가 저장되어 분실되지 않습니다.호출된 함수가 끝나면 호출된 함수의 다음 줄로 되돌아와 코드를 계속 실행합니다. 이전의 국부 변수도 계속 접근할 수 있습니다.소결: 함수의 국부 변수는 함수 내에서만 사용할 수 있고 호출이 끝나면 이 국부 변수들은 모두 방출되고 효력을 상실한다(GC 회수).
    Go 언어에서 함수 호출 형식:
    반환값 변수 목록 = 함수 이름(매개 변수 목록)

    4. 매개 변수 전달 - Golang의 모든 매개 변수는 값 전달


    Go 언어에서 전송 및 반환 매개 변수는 호출 및 반환 시 값을 사용하여 전달됩니다.우리가 주의해야 할 것은 슬라이스 (slice), 포인터 (pointer), 맵 (map) 등 인용형 대상이 가리키는 내용은 매개 변수 전달에서 복제되지 않고 포인터를 복제하는 것이다. 인용을 만드는 것과 유사하다.즉 매개 변수 전달 과정에서 실제 복제된 주소 (포인터) 는 인용 유형이 가리키는 내용을 복제하지 않았다.코드 실행 아래:
    type Data struct {
    	complex  []int     // slice  
    	instance InnerData //  innerdata  
    	ptr      *InnerData // 
    }
    
    // 
    type InnerData struct {
    	a int
    }
    
    func passByValue(inFunc Data) Data {
    	//  
    	fmt.Printf("inFunc value %+v:
    "
    , inFunc) fmt.Printf("inFunc ptr:%p
    "
    , &inFunc) return inFunc } func TestInfunc(t *testing.T) { in := Data{ complex: []int{2, 4, 9}, instance: InnerData{ 7, }, ptr: &InnerData{5}, } // t.Logf("in value:%+v", in) t.Logf("in ptr:%p", &in) // out := passByValue(in) t.Logf("out value:%+v", out) t.Logf("out ptr:%p", &out) } //Run Result: === RUN TestInfunc inFunc value {complex:[2 4 9] instance:{a:7} ptr:0xc000044170}: inFunc ptr:0xc000058420 --- PASS: TestInfunc (0.00s) DataTrasfer_test.go:38: in value:{complex:[2 4 9] instance:{a:7} ptr:0xc000044170} DataTrasfer_test.go:39: in ptr:0xc000058390 DataTrasfer_test.go:42: out value:{complex:[2 4 9] instance:{a:7} ptr:0xc000044170} DataTrasfer_test.go:43: out ptr:0xc0000583f0 PASS

    위의 결과에서 발견:
  • 모든 데이터 구조의 바늘 주소가 바뀌었다. (inptr,outptr,infuncptr)는 모든 구조가 서로 다른 메모리에 저장된다는 것을 의미한다. Date 구조를 함수 내부로 전송하든 반환값을 통해 Data로 전송하든 모두 복제 행위가 발생하고 Data를 새로운 메모리로 복사할 것이다.
  • 모든 Data 구조의 구성원 값은 변하지 않고 그대로 전달됩니다. 즉, 모든 매개 변수는 값 전달입니다.
  • 데이터 구조의 ptr 구성원은 전달 과정에서 변화가 발생하지 않았고 포인터가 함수 매개 변수 전달에서 전달하는 것은 포인터 값일 뿐 포인터가 가리키는 내용을 복사하지 않는다는 것을 나타낸다.

  • 5. 함수 변수 - 함수를 값으로 변수에 저장


    Go에서도 함수는 하나의 유형으로 간주되므로 기본 유형과 같이 변수에 저장될 수 있습니다.
    func hello(str string) string {
    	return str
    }
    
    func TestFuncVar(t *testing.T) {
    	//  
    	var f func(string) string
    
    	//  
    	f = hello
    	t.Log(f("Golang"))
    }
    
    //Run restult:
      === RUN   TestFuncVar
      --- PASS: TestFuncVar (0.00s)
          FuncVar_test.go:17: Golang
      PASS
    

    상기에서 보듯이 함수를 값으로 함수 변수에 전달하고 이 특성을 이용하여 함수를 각 유형의 변수에 부여할 수 있다. 예를 들어 데이터의 처리 함수를 절편 유형의 함수 변수에 부여하고 데이터에 대해 체인식 처리를 할 수 있다.

    6. 익명 함수 - 이름이 없는 일반 함수

  • 함수는 일종의 유형으로 함수 유형에 부여된 변수로 이 특성을 이용하여 익명 함수 역시 변수 방식으로 전달될 수 있다.
  • 익명 함수는 일반적으로 리셋 함수, 패키지 (closure) 를 실현하는 데 사용된다.
  • 익명 함수 자체는 일종의 값(value)으로 각종 용기 유형에 편리하게 저장하여 리셋 함수와 조작 봉인을 실현할 수 있다.

  • 익명 함수 성명, 호출

  • 선언 후 직접 호출
  • func TestUnamefunDir(t *testing.T) {
        // s  
    	s := func(a string) string {
    		return a
    	}("hello")
    
    	t.Log(s)
    }
    
    /* === RUN TestUnamefunDir --- PASS: TestUnamefunDir (0.00s) Unamefunc_test.go:10: hello PASS */
    

    주의: 익명 함수의 마지막} ("hello") 는 익명 함수를 직접 호출합니다.
  • 익명 함수 변수에 값 부여
  • func TestUnamefunVar(t *testing.T) {
    	//  
    	s := func(a string) string {
    		return a
    	}
    	//   s()  
    	t.Log(s("hello"))
    }
    
    /* === RUN TestUnamefunVar --- PASS: TestUnamefunVar (0.00s) Unamefunc_test.go:25: hello PASS */
    

    위의 설명과 함께 익명 함수를 직접 호출하여 구분합니다. 전자는 익명 함수의 반환값을 변수 s에 부여하고, 후자는 익명 함수를 함수 변수 s에 부여합니다.

    익명 함수 리셋 함수 실현


    슬라이스에 대한 반복을 통해 익명 함수를 리셋 함수로 실현합니다.동시에 서로 다른 리셋 함수는 절편에 대한 서로 다른 반복 조작을 실현할 것이다.
    func Range(list []int, f func(int)) { //slice
    	for _, v := range list {
    		f(v)
    	}
    }
    
    func TestRangeList(t *testing.T) {
    	Range([]int{1, 2, 5, 9}, func(b int) { //slice
    		t.Log(b)
    	})
    }
    
    /* === RUN TestRangeList --- PASS: TestRangeList (0.00s) Unamefunc_test.go:49: 1 Unamefunc_test.go:49: 2 Unamefunc_test.go:49: 5 Unamefunc_test.go:49: 9 PASS */
    

    익명 함수 구현 조작 봉인


    행위에 대한 정의를 통해 익명 함수를 맵의 키 값으로 하고 이를 통해 명령의 하위 명령을 실현할 수 있습니다.
    
    //  
    func TestUnameFuncPatch(t *testing.T) {
    	behavior := map[string]func(){
    		"walk": func() {
    			t.Log("Go Walking")
    		},
    		"fly": func() {
    			t.Log("Go Flying")
    		},
    		"jump": func() {
    			t.Log("Go Jumpping")
    		},
    	}
    
    	do := []string{"walk", "fly", "jump", "play"}
    	for i := range do {
    		if f, ok := behavior[do[i]]; ok {
    			f()
    		} else {
    			t.Log("NO Behavior!")
    		}
    	}
    }
    /* === RUN TestUnameFuncPatch --- PASS: TestUnameFuncPatch (0.00s) Unamefunc_test.go:68: Go Walking Unamefunc_test.go:71: Go Flying Unamefunc_test.go:74: Go Jumpping Unamefunc_test.go:83: NO Behavior! PASS */
    

    함수성명 함수호출 함수 매개 변수 전달함수를 값으로 저장익명 함수
    익명 함수 성명 호출 익명 함수 리셋 함수 실현 익명 함수 구현 조작 봉인익명 함수 - 공장 모드
    함수를 인터페이스로 사용총결을 배우고 끊임없이 실천하며 지식을 나눈다.

    좋은 웹페이지 즐겨찾기