<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>dogfootman.com</title>
    <link>https://error37.tistory.com/</link>
    <description>Personal developer's blog</description>
    <language>ko</language>
    <pubDate>Tue, 4 Aug 2026 07:45:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>dogfootman</managingEditor>
    <image>
      <title>dogfootman.com</title>
      <url>https://tistory1.daumcdn.net/tistory/6504319/attach/ec0a70f2968242e7b34c41cfba84b75d</url>
      <link>https://error37.tistory.com</link>
    </image>
    <item>
      <title>privacy</title>
      <link>https://error37.tistory.com/pages/privacy</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Privacy Policy&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Last updated: June 27, 2024&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Welcome to dogfootman.com (&quot;we,&quot; &quot;our,&quot; or &quot;us&quot;). We are committed to protecting your personal information and your right to privacy. If you have any questions or concerns about this privacy notice or our practices with regard to your personal information, please contact us at &lt;a&gt;contact@dogfootman.com&lt;/a&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Information We Collect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;We do not collect any personal information from you.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Contact Us&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If you have questions or comments about this notice, you may contact us at &lt;a&gt;contact@dogfootman.com&lt;/a&gt;.&lt;/p&gt;</description>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/pages/privacy</guid>
      <pubDate>Thu, 27 Jun 2024 20:35:53 +0900</pubDate>
    </item>
    <item>
      <title>[Go] Benchmark 사용법 (How to Use Benchmarks)</title>
      <link>https://error37.tistory.com/14</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Benchmark의 사용법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 기본 사용법&lt;/h4&gt;
&lt;pre class=&quot;go&quot; style=&quot;background-color: #000000; color: #f0f1f2; text-align: start;&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;func BenchmarkXxx(*testing.B)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 형태를 가지고 있으면 벤치마크로 간주되며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-bench 의 플러그가 있으면 go test 의 명령에 의해서 실행된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샘플코드&lt;/p&gt;
&lt;pre id=&quot;code_1719324796430&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

...

func BenchmarkDeepCopyManual(b *testing.B) {
	original := Student{
		Name:    &quot;Alice&quot;,
		Age:     21,
		Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
		Address: Address{
			City:  &quot;San Francisco&quot;,
			State: &quot;CA&quot;,
		},
	}

	for i := 0; i &amp;lt; b.N; i++ {
		_ = deepCopyManual(original)
	}
}

func BenchmarkDeepCopyJSON(b *testing.B) {
	original := Student{
		Name:    &quot;Alice&quot;,
		Age:     21,
		Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
		Address: Address{
			City:  &quot;San Francisco&quot;,
			State: &quot;CA&quot;,
		},
	}

	for i := 0; i &amp;lt; b.N; i++ {
		_, err := deepCopyJSON(original)
		if err != nil {
			b.Fatalf(&quot;Error: %v&quot;, err)
		}
	}
}

func BenchmarkDeepCopyGob(b *testing.B) {
	original := Student{
		Name:    &quot;Alice&quot;,
		Age:     21,
		Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
		Address: Address{
			City:  &quot;San Francisco&quot;,
			State: &quot;CA&quot;,
		},
	}

	for i := 0; i &amp;lt; b.N; i++ {
		_, err := deepCopyGob(original)
		if err != nil {
			b.Fatalf(&quot;Error: %v&quot;, err)
		}
	}
}

func BenchmarkDeepCopyReflect(b *testing.B) {
	original := Student{
		Name:    &quot;Alice&quot;,
		Age:     21,
		Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
		Address: Address{
			City:  &quot;San Francisco&quot;,
			State: &quot;CA&quot;,
		},
	}

	for i := 0; i &amp;lt; b.N; i++ {
		var copyStudent Student
		deepCopyReflect(&amp;amp;copyStudent, original)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와 같이 작성해 &lt;span style=&quot;color: #ee2323;&quot;&gt;xxx_test.go&lt;/span&gt; 의 형태로 저장&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;b.N: 테스트가 반복되는 횟수이며, 자동적으로 계산 된다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 커맨드 예)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-bench&amp;nbsp;regexp&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;'-bench .' or '-bench=.'&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;ex) 모든 벤치마크 함수를 실행한다&lt;/p&gt;
&lt;pre id=&quot;code_1719322410716&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench .&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;참고&lt;/span&gt; 윈도우? 환경에선 -bench=. 의 형태로 사용 할 땐 &quot;&quot;로 감싸주어야 실행이 되는듯 하다&lt;/p&gt;
&lt;pre id=&quot;code_1719322470232&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench=&quot;.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) *JSON형태의 함수를 실행한다&lt;/p&gt;
&lt;pre id=&quot;code_1719322643068&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; go test -bench &quot;.*JSON&quot;
 go test -bench=&quot;.*JSON&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 결과 값&lt;/h4&gt;
&lt;pre id=&quot;code_1719322801577&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS D:\Study\golang\project\deepcopy\deepcopybench&amp;gt; go test -bench .                      
goos: windows
goarch: amd64
pkg: project/deepcopy/deepcopybench
cpu: AMD Ryzen 7 5800X3D 8-Core Processor
BenchmarkDeepCopyManual-16      32283057                33.78 ns/op
BenchmarkDeepCopyJSON-16          561468              2260 ns/op
BenchmarkDeepCopyGob-16            69405             17542 ns/op
BenchmarkDeepCopyReflect-16      4331769               273.4 ns/op
PASS
ok      project/deepcopy/deepcopybench  5.565s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 값 표시 내용&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BenchmarkDeepCopyManual-16
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;BenchmarkDeepCopyManual: 실행된 메서드&lt;/li&gt;
&lt;li&gt;-16: 병렬로 실행 된 고루틴의 수 (= CPU 수)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;32283057: 실행 수&lt;/li&gt;
&lt;li&gt;33.78 ns/op: 평균 실행 속도 ns 단위&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 실행 시간 지정 (-benchtime t)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ex)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;10초 동안 실행&lt;/p&gt;
&lt;pre id=&quot;code_1719323235717&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench . -benchtime 10s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본값은 1s&lt;/p&gt;
&lt;pre id=&quot;code_1719323651272&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS D:\Study\golang\project\deepcopy\deepcopybench&amp;gt; go test -bench . -benchtime 10s
goos: windows
goarch: amd64
pkg: project/deepcopy/deepcopybench
cpu: AMD Ryzen 7 5800X3D 8-Core Processor
BenchmarkDeepCopyManual-16      365221957               33.65 ns/op
BenchmarkDeepCopyJSON-16         5229326              2264 ns/op
BenchmarkDeepCopyGob-16           674312             17697 ns/op
BenchmarkDeepCopyReflect-16     44499788               276.3 ns/op
PASS
ok      project/deepcopy/deepcopybench  54.713s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대략 10배의 시간이 걸린 것을 알수있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 반복 횟수 지정&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(-count n)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ex)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;3회 반복&lt;/p&gt;
&lt;pre id=&quot;code_1719323748093&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench . -count 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본값은 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719323813073&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS D:\Study\golang\project\deepcopy\deepcopybench&amp;gt; go test -bench . -count 3     
goos: windows
goarch: amd64
pkg: project/deepcopy/deepcopybench
cpu: AMD Ryzen 7 5800X3D 8-Core Processor
BenchmarkDeepCopyManual-16      36163094                33.08 ns/op
BenchmarkDeepCopyManual-16      36837273                33.15 ns/op
BenchmarkDeepCopyManual-16      36041664                34.14 ns/op
BenchmarkDeepCopyJSON-16          541074              2209 ns/op
BenchmarkDeepCopyJSON-16          509419              2241 ns/op
BenchmarkDeepCopyJSON-16          526886              2216 ns/op
BenchmarkDeepCopyGob-16            68505             17692 ns/op
BenchmarkDeepCopyGob-16            68971             17452 ns/op
BenchmarkDeepCopyGob-16            67466             17293 ns/op
BenchmarkDeepCopyReflect-16      4377800               276.3 ns/op
BenchmarkDeepCopyReflect-16      4317730               273.9 ns/op
BenchmarkDeepCopyReflect-16      4263261               270.8 ns/op
PASS
ok      project/deepcopy/deepcopybench  16.097s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1초씩 3회 반복 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;5. 메모리 할당량 측정 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(-benchmem)&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1719324089231&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench . -benchmem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719324112789&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS D:\Study\golang\project\deepcopy\deepcopybench&amp;gt; go test -bench . -benchmem
goos: windows
goarch: amd64
pkg: project/deepcopy/deepcopybench
cpu: AMD Ryzen 7 5800X3D 8-Core Processor
BenchmarkDeepCopyManual-16      34451178                33.11 ns/op           48 B/op          1 allocs/op
BenchmarkDeepCopyJSON-16          485587              2297 ns/op             720 B/op         18 allocs/op
BenchmarkDeepCopyGob-16            65107             17625 ns/op           10284 B/op        261 allocs/op
BenchmarkDeepCopyReflect-16      4331397               270.4 ns/op           232 B/op          4 allocs/op
PASS
ok      project/deepcopy/deepcopybench  5.385s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가 된 결과 값의 의미&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;48 B/op: 각 실행에서 평균적으로 48바이트의 메모리가 할당&lt;/li&gt;
&lt;li&gt;1 allocs/op: 각 실행에서 평균적으로 1번의 메모리가 할당&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;6.&lt;span&gt; CPU 코어 수 지정 &lt;/span&gt;&amp;nbsp;(-cpu n,n,n...)&lt;/h4&gt;
&lt;pre id=&quot;code_1719324331950&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench . -cpu 1,4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각 CPU의 코어를 1개 4개씩 사용하여 실행한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719324422985&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PS D:\Study\golang\project\deepcopy\deepcopybench&amp;gt; go test -bench . -cpu 1,4 
goos: windows
goarch: amd64
pkg: project/deepcopy/deepcopybench
cpu: AMD Ryzen 7 5800X3D 8-Core Processor
BenchmarkDeepCopyManual         35368495                32.29 ns/op
BenchmarkDeepCopyManual-4       36784426                33.96 ns/op
BenchmarkDeepCopyJSON             520654              2265 ns/op
BenchmarkDeepCopyJSON-4           556598              2231 ns/op
BenchmarkDeepCopyGob               68617             17370 ns/op
BenchmarkDeepCopyGob-4             67000             17880 ns/op
BenchmarkDeepCopyReflect         4287910               270.8 ns/op
BenchmarkDeepCopyReflect-4       4495464               277.1 ns/op
PASS
ok      project/deepcopy/deepcopybench  10.904s&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;7. 기타 옵션의 확인&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;go help testflag 명령어나&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 참조 사이트를 통해서 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;참조:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://pkg.go.dev/testing#hdr-Benchmarks&quot;&gt;https://pkg.go.dev/testing#hdr-Benchmarks&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719324569673&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;testing package - testing - Go Packages&quot; data-og-description=&quot;Discover Packages Standard library testing Version: go1.22.4 Opens a new window with list of versions in this module. Published: Jun 4, 2024 License: BSD-3-Clause Opens a new window with license information. Imports: 24 Opens a new window with list of impo&quot; data-og-host=&quot;pkg.go.dev&quot; data-og-source-url=&quot;https://pkg.go.dev/testing#hdr-Benchmarks&quot; data-og-url=&quot;https://pkg.go.dev/testing#hdr-Benchmarks&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/testing#hdr-Benchmarks&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pkg.go.dev/testing#hdr-Benchmarks&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;testing package - testing - Go Packages&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Discover Packages Standard library testing Version: go1.22.4 Opens a new window with list of versions in this module. Published: Jun 4, 2024 License: BSD-3-Clause Opens a new window with license information. Imports: 24 Opens a new window with list of impo&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pkg.go.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;참조:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://pkg.go.dev/cmd/go#hdr-Testing_flags&quot;&gt;https://pkg.go.dev/cmd/go#hdr-Testing_flags&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719324574863&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;go command - cmd/go - Go Packages&quot; data-og-description=&quot;Discover Packages Standard library cmd go Version: go1.22.4 Opens a new window with list of versions in this module. Published: Jun 4, 2024 License: BSD-3-Clause Opens a new window with license information. Imports: 34 Opens a new window with list of impor&quot; data-og-host=&quot;pkg.go.dev&quot; data-og-source-url=&quot;https://pkg.go.dev/cmd/go#hdr-Testing_flags&quot; data-og-url=&quot;https://pkg.go.dev/cmd/go#hdr-Testing_flags&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/cmd/go#hdr-Testing_flags&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pkg.go.dev/cmd/go#hdr-Testing_flags&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;go command - cmd/go - Go Packages&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Discover Packages Standard library cmd go Version: go1.22.4 Opens a new window with list of versions in this module. Published: Jun 4, 2024 License: BSD-3-Clause Opens a new window with license information. Imports: 34 Opens a new window with list of impor&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pkg.go.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>bench</category>
      <category>benchmark</category>
      <category>Golang</category>
      <category>Performance</category>
      <category>test</category>
      <category>고랭</category>
      <category>벤치마킹</category>
      <category>성능</category>
      <category>테스트</category>
      <category>퍼포먼스</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/14</guid>
      <comments>https://error37.tistory.com/14#entry14comment</comments>
      <pubDate>Tue, 25 Jun 2024 23:18:37 +0900</pubDate>
    </item>
    <item>
      <title>[Go] 구조체를 여러가지 방법으로 깊은 복사 하는 방법 + 성능비교 (How to deep copy a struct in various ways + Performance comparison)</title>
      <link>https://error37.tistory.com/13</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조체를 여러가지 방법으로 깊은 복사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 복사 방법의 성능 비교 (Benchmark)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벤치마크 참고: &lt;a href=&quot;https://dogfootman.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dogfootman.com/14&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719325217477&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Go] Benchmark 사용법 (How to Use Benchmarks)&quot; data-og-description=&quot;개요Benchmark의 사용법&amp;nbsp;&amp;nbsp;&amp;nbsp;1. 기본 사용법func BenchmarkXxx(*testing.B)&amp;nbsp;의 형태를 가지고 있으면 벤치마크로 간주되며-bench 의 플러그가 있으면 go test 의 명령에 의해서 실행된다&amp;nbsp;&amp;nbsp;샘플코드package main...f&quot; data-og-host=&quot;dogfootman.com&quot; data-og-source-url=&quot;https://dogfootman.com/14&quot; data-og-url=&quot;https://dogfootman.com/14&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c1ucan/hyWoLTB8fz/SrlzCEnoJoJKR6aeZ3Mm41/img.png?width=419&amp;amp;height=97&amp;amp;face=0_0_419_97,https://scrap.kakaocdn.net/dn/68lIt/hyWrLdnUph/mKdWOhaDyrSawKXmUuXGR0/img.png?width=419&amp;amp;height=97&amp;amp;face=0_0_419_97&quot;&gt;&lt;a href=&quot;https://dogfootman.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dogfootman.com/14&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c1ucan/hyWoLTB8fz/SrlzCEnoJoJKR6aeZ3Mm41/img.png?width=419&amp;amp;height=97&amp;amp;face=0_0_419_97,https://scrap.kakaocdn.net/dn/68lIt/hyWrLdnUph/mKdWOhaDyrSawKXmUuXGR0/img.png?width=419&amp;amp;height=97&amp;amp;face=0_0_419_97');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Go] Benchmark 사용법 (How to Use Benchmarks)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요Benchmark의 사용법&amp;nbsp;&amp;nbsp;&amp;nbsp;1. 기본 사용법func BenchmarkXxx(*testing.B)&amp;nbsp;의 형태를 가지고 있으면 벤치마크로 간주되며-bench 의 플러그가 있으면 go test 의 명령에 의해서 실행된다&amp;nbsp;&amp;nbsp;샘플코드package main...f&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dogfootman.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 수동으로 깊은 복사&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type Address struct {
    City  string
    State string
}

type Student struct {
    Name    string
    Age     int
    Hobbies []string
    Address Address
}

func deepCopyStudent(original Student) Student {
    hobbiesCopy := make([]string, len(original.Hobbies))
    copy(hobbiesCopy, original.Hobbies)

    return Student{
       Name:    original.Name,
       Age:     original.Age,
       Hobbies: hobbiesCopy,
       Address: Address{
          City:  original.Address.City,
          State: original.Address.State,
       },
    }
}

func main() {
    original := Student{
       Name:    &quot;Alice&quot;,
       Age:     21,
       Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
       Address: Address{
          City:  &quot;San Francisco&quot;,
          State: &quot;CA&quot;,
       },
    }

    // deep copy
    copyStudent := deepCopyStudent(original)

    // update original
    original.Name = &quot;Bob&quot;
    original.Hobbies[0] = &quot;Running&quot;
    original.Address.City = &quot;Los Angeles&quot;

    fmt.Println(&quot;Original:&quot;, original)
    fmt.Println(&quot;Copy:&quot;, copyStudent)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;result:&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719318972076&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Original: {Bob 21 [Running Cycling Swimming] {Los Angeles CA}}
Copy: {Alice 21 [Reading Cycling Swimming] {San Francisco CA}}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Json을 이용한 깊은 복사&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package main

import (
    &quot;encoding/json&quot;
    &quot;fmt&quot;
)

type Address struct {
    City  string
    State string
}

type Student struct {
    Name    string
    Age     int
    Hobbies []string
    Address Address
}

func deepCopyStudent(original Student) (Student, error) {
    var copyStudent Student
    data, err := json.Marshal(original)
    if err != nil {
       return copyStudent, err
    }
    err = json.Unmarshal(data, &amp;amp;copyStudent)
    return copyStudent, err
}

func main() {
    original := Student{
       Name:    &quot;Alice&quot;,
       Age:     21,
       Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
       Address: Address{
          City:  &quot;San Francisco&quot;,
          State: &quot;CA&quot;,
       },
    }

    // deep copy
    copyStudent, err := deepCopyStudent(original)
    if err != nil {
       fmt.Println(&quot;Error:&quot;, err)
       return
    }

    // update original
    original.Name = &quot;Bob&quot;
    original.Hobbies[0] = &quot;Running&quot;
    original.Address.City = &quot;Los Angeles&quot;

    fmt.Println(&quot;Original:&quot;, original)
    fmt.Println(&quot;Copy:&quot;, copyStudent)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;result:&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719319189998&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Original: {Bob 21 [Running Cycling Swimming] {Los Angeles CA}}
Copy: {Alice 21 [Reading Cycling Swimming] {San Francisco CA}}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 리플렉션을 이용한 깊은 복사&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package main

import (
    &quot;fmt&quot;
    &quot;reflect&quot;
)

type Address struct {
    City  string
    State string
}

type Student struct {
    Name    string
    Age     int
    Hobbies []string
    Address Address
}

func deepCopy(dst, src interface{}) {
    srcVal := reflect.ValueOf(src)
    dstVal := reflect.ValueOf(dst).Elem()
    deepCopyValue(dstVal, srcVal)
}

func deepCopyValue(dst, src reflect.Value) {
    switch src.Kind() {
    case reflect.Ptr:
       if !src.IsNil() {
          dst.Set(reflect.New(src.Elem().Type()))
          deepCopyValue(dst.Elem(), src.Elem())
       }
    case reflect.Struct:
       for i := 0; i &amp;lt; src.NumField(); i++ {
          deepCopyValue(dst.Field(i), src.Field(i))
       }
    case reflect.Slice:
       if !src.IsNil() {
          dst.Set(reflect.MakeSlice(src.Type(), src.Len(), src.Cap()))
          for i := 0; i &amp;lt; src.Len(); i++ {
             deepCopyValue(dst.Index(i), src.Index(i))
          }
       }
    default:
       dst.Set(src)
    }
}

func main() {
    original := Student{
       Name:    &quot;Alice&quot;,
       Age:     21,
       Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
       Address: Address{
          City:  &quot;San Francisco&quot;,
          State: &quot;CA&quot;,
       },
    }

    // deep copy
    var copyStudent Student
    deepCopy(&amp;amp;copyStudent, original)

    // update original
    original.Name = &quot;Bob&quot;
    original.Hobbies[0] = &quot;Running&quot;
    original.Address.City = &quot;Los Angeles&quot;

    fmt.Println(&quot;Original:&quot;, original)
    fmt.Println(&quot;Copy:&quot;, copyStudent)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;result:&lt;/p&gt;
&lt;pre id=&quot;code_1719319342667&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Original: {Bob 21 [Running Cycling Swimming] {Los Angeles CA}}
Copy: {Alice 21 [Reading Cycling Swimming] {San Francisco CA}}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. Gob을&amp;nbsp;이용한&amp;nbsp;깊은&amp;nbsp;복사&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package main

import (
    &quot;bytes&quot;
    &quot;encoding/gob&quot;
    &quot;fmt&quot;
)

type Address struct {
    City  string
    State string
}

type Student struct {
    Name    string
    Age     int
    Hobbies []string
    Address Address
}

func deepCopyStudent(original Student) (Student, error) {
    var copyStudent Student
    buf := new(bytes.Buffer)
    enc := gob.NewEncoder(buf)
    dec := gob.NewDecoder(buf)
    if err := enc.Encode(original); err != nil {
       return copyStudent, err
    }
    if err := dec.Decode(&amp;amp;copyStudent); err != nil {
       return copyStudent, err
    }
    return copyStudent, nil
}

func main() {
    original := Student{
       Name:    &quot;Alice&quot;,
       Age:     21,
       Hobbies: []string{&quot;Reading&quot;, &quot;Cycling&quot;, &quot;Swimming&quot;},
       Address: Address{
          City:  &quot;San Francisco&quot;,
          State: &quot;CA&quot;,
       },
    }

    // deep copy
    copyStudent, err := deepCopyStudent(original)
    if err != nil {
       fmt.Println(&quot;Error:&quot;, err)
       return
    }

    // update original
    original.Name = &quot;Bob&quot;
    original.Hobbies[0] = &quot;Running&quot;
    original.Address.City = &quot;Los Angeles&quot;

    fmt.Println(&quot;Original:&quot;, original)
    fmt.Println(&quot;Copy:&quot;, copyStudent)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;result:&lt;/p&gt;
&lt;pre id=&quot;code_1719319526230&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Original: {Bob 21 [Running Cycling Swimming] {Los Angeles CA}}
Copy: {Alice 21 [Reading Cycling Swimming] {San Francisco CA}}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5. 성능 비교&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 커맨드&lt;/p&gt;
&lt;pre id=&quot;code_1719325484954&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;go test -bench=&quot;.&quot; -benchmem&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 코드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/psKpv/btsIcVO2JXP/oIfwU3E2QkkK1UBKkSwD1k/main_test.go?attach=1&amp;amp;knm=tfile.go&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;main_test.go&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 85px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 11.3178%; height: 17px;&quot;&gt;방법&lt;/td&gt;
&lt;td style=&quot;width: 21.5504%; height: 17px;&quot;&gt;실행 횟수 (1초)&lt;/td&gt;
&lt;td style=&quot;width: 18.876%; height: 17px;&quot;&gt;평균 실행 속도&lt;/td&gt;
&lt;td style=&quot;width: 23.4109%; height: 17px;&quot;&gt;평균 메모리 사용량&lt;/td&gt;
&lt;td style=&quot;width: 23.876%; height: 17px;&quot;&gt;메모리 할당 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 11.3178%; height: 17px;&quot;&gt;수동&lt;/td&gt;
&lt;td style=&quot;width: 21.5504%; height: 17px;&quot;&gt;35818543&lt;/td&gt;
&lt;td style=&quot;width: 18.876%; height: 17px;&quot;&gt;32.92&amp;nbsp;ns/op&lt;/td&gt;
&lt;td style=&quot;width: 23.4109%; height: 17px;&quot;&gt;48&amp;nbsp;B/op&lt;/td&gt;
&lt;td style=&quot;width: 23.876%; height: 17px;&quot;&gt;1&amp;nbsp;allocs/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 11.3178%; height: 17px;&quot;&gt;리플렉션&lt;/td&gt;
&lt;td style=&quot;width: 21.5504%; height: 17px;&quot;&gt;4314712&lt;/td&gt;
&lt;td style=&quot;width: 18.876%; height: 17px;&quot;&gt;272.6&amp;nbsp;ns/op&lt;/td&gt;
&lt;td style=&quot;width: 23.4109%; height: 17px;&quot;&gt;232&amp;nbsp;B/op&lt;/td&gt;
&lt;td style=&quot;width: 23.876%; height: 17px;&quot;&gt;4&amp;nbsp;allocs/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 11.3178%; height: 17px;&quot;&gt;JSON&lt;/td&gt;
&lt;td style=&quot;width: 21.5504%; height: 17px;&quot;&gt;518389&lt;/td&gt;
&lt;td style=&quot;width: 18.876%; height: 17px;&quot;&gt;2220&amp;nbsp;ns/op&lt;/td&gt;
&lt;td style=&quot;width: 23.4109%; height: 17px;&quot;&gt;720&amp;nbsp;B/op&lt;/td&gt;
&lt;td style=&quot;width: 23.876%; height: 17px;&quot;&gt;18&amp;nbsp;allocs/op&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 11.3178%; height: 17px;&quot;&gt;Gob&lt;/td&gt;
&lt;td style=&quot;width: 21.5504%; height: 17px;&quot;&gt;71022&lt;/td&gt;
&lt;td style=&quot;width: 18.876%; height: 17px;&quot;&gt;17085&amp;nbsp;ns/op&lt;/td&gt;
&lt;td style=&quot;width: 23.4109%; height: 17px;&quot;&gt;10284&amp;nbsp;B/op&lt;/td&gt;
&lt;td style=&quot;width: 23.876%; height: 17px;&quot;&gt;261&amp;nbsp;allocs/op&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 테스트 코드에서의 속도는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수동 &amp;gt; 리플렉션 &amp;gt; JSON &amp;gt; Gob&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 순서로 빠르고 메모리 사용량도 적다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>benchmark</category>
      <category>deep copy</category>
      <category>go</category>
      <category>gob</category>
      <category>Golang</category>
      <category>json</category>
      <category>Performance</category>
      <category>reflect</category>
      <category>struct</category>
      <category>test</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/13</guid>
      <comments>https://error37.tistory.com/13#entry13comment</comments>
      <pubDate>Tue, 25 Jun 2024 22:02:44 +0900</pubDate>
    </item>
    <item>
      <title>[Go] 제네릭 사용 예 (Example of using generics)</title>
      <link>https://error37.tistory.com/12</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;go 1.18에서 추가 된 제네릭의 사용 예&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 함수에서의 사용&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func Filter[T any](list []T, predicate func(T) bool) []T {
	var result []T
	for _, v := range list {
		if predicate(v) {
			result = append(result, v)
		}
	}
	return result
}

func main() {
	
	// 짝수만 필터
	nums := []int{1, 2, 3, 4, 5, 6}
	evens := Filter(nums, func(n int) bool {
		return n%2 == 0
	})
	fmt.Println(evens) // [2 4 6]

	// 길이가 5가 넘는 문자열만 필터
	strings := []string{&quot;apple&quot;, &quot;banana&quot;, &quot;cherry&quot;, &quot;date&quot;}
	filteredStrings := Filter(strings, func(s string) bool {
		return len(s) &amp;gt; 5
	})
	fmt.Println(filteredStrings) // [&quot;banana&quot;, &quot;cherry&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;T는 타입 매개변수&lt;/li&gt;
&lt;li&gt;any&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btIf6E/btsH8kitf5K/auQ4hOS6C1YKcctVuzkhR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btIf6E/btsH8kitf5K/auQ4hOS6C1YKcctVuzkhR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btIf6E/btsH8kitf5K/auQ4hOS6C1YKcctVuzkhR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtIf6E%2FbtsH8kitf5K%2FauQ4hOS6C1YKcctVuzkhR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;68&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 구조체에서의 사용&lt;/h4&gt;
&lt;pre id=&quot;code_1719069705259&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type Stack[T any] struct {
	elements []T
}

func (s *Stack[T]) Push(element T) {
	s.elements = append(s.elements, element)
}

func (s *Stack[T]) Pop() T {
	if len(s.elements) == 0 {
		var zero T
		return zero
	}
	element := s.elements[len(s.elements)-1]
	s.elements = s.elements[:len(s.elements)-1]
	return element
}

func main() {
	intStack := Stack[int]{}
	intStack.Push(1)
	intStack.Push(2)
	fmt.Println(intStack.Pop()) // 2

	stringStack := Stack[string]{}
	stringStack.Push(&quot;hello&quot;)
	stringStack.Push(&quot;world&quot;)
	fmt.Println(stringStack.Pop()) // world
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719070928108&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type Pair[T any] struct {
	first, second T
}

func (p Pair[T]) Swap() Pair[T] {
	return Pair[T]{p.second, p.first}
}

func main() {
	intPair := Pair[int]{1, 2}
	fmt.Println(intPair.Swap()) // {2 1}

	stringPair := Pair[string]{&quot;hello&quot;, &quot;world&quot;}
	fmt.Println(stringPair.Swap()) // {world hello}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;3. 인터페이스를 통한 타입 제한&lt;/h4&gt;
&lt;pre id=&quot;code_1719070107183&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type Adder interface {
	Add() int
}

// Calculator1 Add 함수만 가지는 구조체
type Calculator1 struct {
	a int
	b int
}

func (c Calculator1) Add() int {
	return c.a + c.b
}

// Calculator2 Minus 함수만 가지는 구조체
type Calculator2 struct {
	a int
	b int
}

func (c Calculator2) Minus() int {
	return c.a - c.b
}

func AddValues[T Adder](adder T) int {
	return adder.Add()
}

func main() {
	// Calculator 인스턴스를 생성
	calc := Calculator1{2, 3}

	// AddValues 함수를 호출하여 두 값의 합을 계산
	result := AddValues(calc)
	fmt.Println(result) // 5

	// Calculator2 인스턴스를 생성
	//calc2 := Calculator2{5, 3}
	//result2 := AddValues(calc2) // T (type Calculator2) does not satisfy Adder (missing method Add) 에러 발생
	//fmt.Println(result2)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Calculator1 구조체는 Adder 인터페이스를 구현하므로 AddValues 함수에 전달 가능&lt;/li&gt;
&lt;li&gt;Calculator2 구조체는 Adder 인터페이스를 구현하지 않으므로 AddValues 함수에 전달 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1719070278280&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

type Number interface {
	int | float64
}

func Average[T Number](values []T) T {
	var sum T
	for _, v := range values {
		sum += v
	}
	return sum / T(len(values))
}

func main() {
	fmt.Println(Average([]int{1, 2, 3, 4, 5}))        // 3 (int)
	fmt.Println(Average([]float64{1.1, 2.2, 3.3}))    // 2.2 (float64)
	//fmt.Println(Average([]string{&quot;apple&quot;, &quot;banana&quot;})) // string does not satisfy Number (string missing in int | float64) 에러 발생
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://go.dev/blog/intro-generics&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://go.dev/blog/intro-generics&lt;/a&gt;&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>1.18</category>
      <category>Filter</category>
      <category>Generic</category>
      <category>Golang</category>
      <category>Interface</category>
      <category>struct</category>
      <category>고랭</category>
      <category>구조체</category>
      <category>제네릭</category>
      <category>필터</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/12</guid>
      <comments>https://error37.tistory.com/12#entry12comment</comments>
      <pubDate>Sun, 23 Jun 2024 00:58:07 +0900</pubDate>
    </item>
    <item>
      <title>[Go] 고랭에서의 예외처리 (exception handling in golang)</title>
      <link>https://error37.tistory.com/11</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;b&gt;예외 처리&lt;/b&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 언어에서 예외는 프로그램 실행 중에 발생하는 비정상적인 상황을 처리하기 위한 메커니즘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예외는 try-catch 블록을 사용하여 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt; &lt;b&gt;패닉 처리&lt;/b&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go 언어에서는 패닉은 프로그램이 정상적으로 계속 실행될 수 없는 심각한 오류가 발생했을 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패닉이 발생하면 현재 고루틴은 즉시 중단되고, defer로 등록된 함수들이 호출된 후 프로그램이 종료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;recover를 사용하여 패닉을 복구할 수 있지만, 일반적인 오류 처리 메커니즘으로 사용되지는 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. panic이 발생하는 프로그램&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    fmt.Println(&quot;Start!!&quot;)
    divide(10, 0)
    fmt.Println(&quot;End&quot;)
}

func divide(x, y int) int {
    return x / y
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0으로 나누어 패닉을 발생 시킨다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;main 함수에서 시작 메세지를 출력&lt;/li&gt;
&lt;li&gt;divide 함수를 호출&lt;/li&gt;
&lt;li&gt;y에 0을 전달 했기때문에 panic이 발생&lt;/li&gt;
&lt;li&gt;종료메세지는 실행 되지 않는다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과:&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718978478342&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Start!!
panic: runtime error: integer divide by zero

goroutine 1 [running]:
main.divide(...)
	D:/Study/golang/project/panic/main.go:12
main.main()
	D:/Study/golang/project/panic/main.go:7 +0x52&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. recovery를 추가한 프로그램&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func main() {
    fmt.Println(&quot;Start!!&quot;)
    divide(10, 0)
    fmt.Println(&quot;End!!&quot;)
}

func divide(x, y int) {
    defer func() {
       if r := recover(); r != nil {
          fmt.Println(&quot;Recovery: &quot;, r)
       }
    }()

    fmt.Println(&quot;Start divide: &quot;, x, y)
    result := x / y
    fmt.Println(&quot;Result: &quot;, result)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;divide의 첫줄에 defer func을 추가&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;main 함수에서 시작 메세지를 출력&lt;/li&gt;
&lt;li&gt;divide 함수를 호출&lt;/li&gt;
&lt;li&gt;y에 0을 전달 했기때문에 panic이 발생&lt;/li&gt;
&lt;li&gt;func 실행이 종료되었으므로 defer의 func이 실행&lt;/li&gt;
&lt;li&gt;recovery가 nil이 아니므로 리커버리의 메세지를 출력&lt;/li&gt;
&lt;li&gt;Result는 출력되지 않는다.&lt;/li&gt;
&lt;li&gt;main 함수에서 종료 메세지가 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과:&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718979100568&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Start!!
Start divide:  10 0
Recovery:  runtime error: integer divide by zero
End!!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. error를 반환하여 처리한 프로그램&lt;/h4&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package main

import (
    &quot;errors&quot;
    &quot;fmt&quot;
)

func main() {
    fmt.Println(&quot;Start!!&quot;)
    result, err := divide(10, 0)
    if err != nil {
       fmt.Println(&quot;Error:&quot;, err)
    } else {
       fmt.Println(&quot;Result:&quot;, result)
    }
    fmt.Println(&quot;End!!&quot;)
}

func divide(x, y int) (int, error) {
    if y == 0 {
       return 0, errors.New(&quot;cannot divide by zero&quot;)
    }
    return x / y, nil
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;y이 0이 전달 될 경우 panic이 발생 할 것이 예측 가능하므로 명시적으로 error를 반환&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;main 함수에서 시작 메세지를 출력&lt;/li&gt;
&lt;li&gt;divide 함수를 호출&lt;/li&gt;
&lt;li&gt;y에 0을 전달 되었기 때문에 error를 명시적으로 반환&lt;/li&gt;
&lt;li&gt;main 함수에서 err가 있으면 에러 메세지를 출력, 없으면 결과 값을 출력&lt;/li&gt;
&lt;li&gt;main 함수에서 종료 메세지가 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과:&lt;/p&gt;
&lt;pre id=&quot;code_1718982770098&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Start!!
Error: cannot divide by zero
End&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. panic recovery나 return error를 사용 할 때 고려 해야 할 사항&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;패닉을 사용할 때:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;심각한 오류&lt;/b&gt;: 패닉은 복구할 수 없는 심각한 오류 상황에서만 사용해야 함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;즉시 중단&lt;/b&gt;: 프로그램을 즉시 중단시키므로, recovery를 통해 적절한 처리가 필요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디버깅&lt;/b&gt;: 패닉이 발생한 위치와 원인을 파악하기 쉽도록 패닉 메세지에 대한 정보를 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;에러를 반환할 때:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;예측 가능한 오류&lt;/b&gt;: 예상할 수 있는 오류 상황에서는 에러를 반환하는 것을 우선적으로 고려&lt;/li&gt;
&lt;li&gt;&lt;b&gt;오류 처리&lt;/b&gt;: 호출자에게 오류를 알려, 호출자에서&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;적절한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 조치를 취할 수 있도록 함&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://go.dev/blog/defer-panic-and-recover&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://go.dev/blog/defer-panic-and-recover&lt;/a&gt;&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>Error</category>
      <category>Exception</category>
      <category>Golang</category>
      <category>Panic</category>
      <category>recovery</category>
      <category>고랭</category>
      <category>리커버리</category>
      <category>에러</category>
      <category>예외</category>
      <category>패닉</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/11</guid>
      <comments>https://error37.tistory.com/11#entry11comment</comments>
      <pubDate>Sat, 22 Jun 2024 00:38:49 +0900</pubDate>
    </item>
    <item>
      <title>[Go] import cycle not allowed - 해결 방안1: interface를 활용한 해결 방안</title>
      <link>https://error37.tistory.com/10</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 import cycle not allowed 에러를 인터페이스를 활용해 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dogfootman.com/9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dogfootman.com/9&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719325980047&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Go] import cycle not allowed - 예제&quot; data-og-description=&quot;개요import cycle not allowed가 발생하는 경우+---------------------+ +----------------------+| user 패키지 | | board 패키지 || | | || +-----------------+ | | +------------------+ || | User Struct | | | | Post Struct | || +-----------------+ |&quot; data-og-host=&quot;dogfootman.com&quot; data-og-source-url=&quot;https://dogfootman.com/9&quot; data-og-url=&quot;https://dogfootman.com/9&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dSfodw/hyWrLdn0bq/MClnKzlbrtxCuQpU5aLoP1/img.png?width=610&amp;amp;height=453&amp;amp;face=0_0_610_453,https://scrap.kakaocdn.net/dn/bFzpQO/hyWrK6A936/QYydbmOeuPqFqKYxkZNo01/img.png?width=610&amp;amp;height=453&amp;amp;face=0_0_610_453&quot;&gt;&lt;a href=&quot;https://dogfootman.com/9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dogfootman.com/9&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dSfodw/hyWrLdn0bq/MClnKzlbrtxCuQpU5aLoP1/img.png?width=610&amp;amp;height=453&amp;amp;face=0_0_610_453,https://scrap.kakaocdn.net/dn/bFzpQO/hyWrK6A936/QYydbmOeuPqFqKYxkZNo01/img.png?width=610&amp;amp;height=453&amp;amp;face=0_0_610_453');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Go] import cycle not allowed - 예제&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요import cycle not allowed가 발생하는 경우+---------------------+ +----------------------+| user 패키지 | | board 패키지 || | | || +-----------------+ | | +------------------+ || | User Struct | | | | Post Struct | || +-----------------+ |&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dogfootman.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. 프로젝트 구조&lt;/h4&gt;
&lt;pre id=&quot;code_1718643397579&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/dependency2
│
├── main.go
├── user
│   └── user.go
└── board
│   └── board.go
└── interfaces
    └── interfaces.go&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의존 관계를 없애기 위한 intefaces 패키지를 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2. 코드&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;interfaces.go&lt;/p&gt;
&lt;pre id=&quot;code_1718643819551&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package interfaces

type Board interface {
    GetLastPostByUserID(userID int) string
}

type User interface {
    GetUserNameByID(userID int) string
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board.go&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package board

import (
    &quot;dependency2/interfaces&quot;
)

type Post struct {
    ID      int
    UserID  int
    Title   string
    Content string
}

var posts = []*Post{
    {ID: 1, UserID: 1, Title: &quot;First Post&quot;, Content: &quot;This is Alice's first post&quot;},
    {ID: 2, UserID: 2, Title: &quot;Hello World&quot;, Content: &quot;This is Bob's first post&quot;},
}

type PostInfo struct {
    *Post
    UserName string
}

type Impl struct {
    User interfaces.User
}

func (b *Impl) GetPostList() []*PostInfo {

    var postList []*PostInfo
    for _, post := range posts {
       // 각 게시글 작성자의 이름을 가져옴
       userName := b.User.GetUserNameByID(post.UserID)
       info := &amp;amp;PostInfo{Post: post, UserName: userName}
       postList = append(postList, info)
    }

    return postList
}

func (b *Impl) GetLastPostByUserID(userID int) string {
    for i := len(posts) - 1; i &amp;gt;= 0; i-- {
       if posts[i].UserID == userID {
          return posts[i].Title
       }
    }
    return &quot;No posts found&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;user.go&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;package user

import (
    &quot;dependency2/interfaces&quot;
)

type User struct {
    ID        int
    Name      string
    FriendIDs []int
}

var users = []*User{
    {ID: 1, Name: &quot;Alice&quot;, FriendIDs: []int{2}},
    {ID: 2, Name: &quot;Bob&quot;, FriendIDs: []int{1}},
}

type FriendInfo struct {
    *User
    LastPost string
}

type Impl struct {
    Board interfaces.Board
}

func (u *Impl) GetFriendList(userID int) []*FriendInfo {

    user := u.GetUserByID(userID)
    if user == nil || len(user.FriendIDs) == 0 {
       return nil
    }

    var infoList []*FriendInfo
    for _, friendID := range user.FriendIDs {
       friendUser := u.GetUserByID(friendID)
       // 유저의 마지막 글을 취득
       lastPost := u.Board.GetLastPostByUserID(friendUser.ID)
       info := &amp;amp;FriendInfo{User: friendUser, LastPost: lastPost}
       infoList = append(infoList, info)
    }
    return infoList
}

func (u *Impl) GetUserByID(userID int) *User {
    for _, user := range users {
       if user.ID == userID {
          return user
       }
    }
    return nil
}

func (u *Impl) GetUserNameByID(userID int) string {
    user := u.GetUserByID(userID)
    if user == nil {
       return &quot;&quot;
    }
    return u.GetUserByID(userID).Name
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main.go&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package main

import (
    &quot;dependency2/board&quot;
    &quot;dependency2/user&quot;
    &quot;encoding/json&quot;
    &quot;fmt&quot;
)

func main() {

    boardService := &amp;amp;board.Impl{}
    userService := &amp;amp;user.Impl{}

    boardService.User = userService
    userService.Board = boardService

    friendList := userService.GetFriendList(1)
    friendListJsonData, _ := json.Marshal(friendList)
    fmt.Println(&quot;Friend List:&quot;, string(friendListJsonData))

    postList := boardService.GetPostList()
    postListJsonData, _ := json.Marshal(postList)
    fmt.Println(&quot;Post List:&quot;, string(postListJsonData))
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 서비스를 각각의 서비스의 인터페이스를 통해&amp;nbsp; 주입&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;boardService.User = userService&lt;/li&gt;
&lt;li&gt;userService.Board = boardService&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 실행 결과&lt;/p&gt;
&lt;pre id=&quot;code_1718643598148&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Friend List: [{&quot;ID&quot;:2,&quot;Name&quot;:&quot;Bob&quot;,&quot;FriendIDs&quot;:[1],&quot;LastPost&quot;:&quot;Hello World&quot;}]
Post List: [{&quot;ID&quot;:1,&quot;UserID&quot;:1,&quot;Title&quot;:&quot;First Post&quot;,&quot;Content&quot;:&quot;This is Alice's first post&quot;,&quot;UserName&quot;:&quot;Alice&quot;},{&quot;ID&quot;:2,&quot;UserID&quot;:2,&quot;Title&quot;:&quot;Hello World&quot;,&quot;Content&quot;:&quot;This is Bob's first post&quot;,&quot;UserName&quot;:&quot;Bob&quot;}]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 없이 실행이 가능한 것을 확인&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>cycle not allowed</category>
      <category>Dependency</category>
      <category>Golang</category>
      <category>injection</category>
      <category>Interface</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/10</guid>
      <comments>https://error37.tistory.com/10#entry10comment</comments>
      <pubDate>Tue, 18 Jun 2024 02:05:06 +0900</pubDate>
    </item>
    <item>
      <title>[Go] import cycle not allowed - 예제</title>
      <link>https://error37.tistory.com/9</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import cycle not allowed가 발생하는 경우&lt;/p&gt;
&lt;pre id=&quot;code_1718638625552&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;+---------------------+       +----------------------+
|      user 패키지    |       |      board 패키지     |
|                     |       |                      |
| +-----------------+ |       | +------------------+ |
| |   User Struct   | |       | |    Post Struct   | |
| +-----------------+ |       | +------------------+ |
|                     |       |                      |
| +-----------------+ |       | +------------------+ |
| | GetFriendList() | &amp;lt;-------+ | GetLastPostByUserID() |
| +-----------------+ |       | +------------------+ |
|                     |       |                      |
| +-----------------+ |       | +------------------+ |
| | GetUserNameByID() +-------&amp;gt; | GetPostList()    | |
| +-----------------+ |       | +------------------+ |
|                     |       |                      |
+---------------------+       +----------------------+&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;user패키지&lt;/span&gt;에는 친구 리스트를 반환하는 func가 존재하고 &amp;lt;- &lt;span style=&quot;color: #006dd7;&quot;&gt;board패키지&lt;/span&gt;로 부터 마지막 작성한 게시글을 취득&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt; board패키지&lt;/span&gt;에서는 게시판 글 리스트 반환하는 func이 존재 -&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;user패키지&lt;/span&gt;로 부터 유저의 이름을 취득&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 프로젝트 구조&lt;/h4&gt;
&lt;pre id=&quot;code_1718639008592&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/dependency1
│
├── main.go
├── user
│   └── user.go
└── board
    └── board.go&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 코드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main.go&lt;/p&gt;
&lt;pre id=&quot;code_1718638900631&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
	&quot;dependency1/board&quot;
	&quot;dependency1/user&quot;
	&quot;fmt&quot;
)

func main() {
	friendList := user.GetFriendList(1)
	fmt.Println(&quot;Friend List:&quot;, friendList)

	postList := board.GetPostList()
	fmt.Println(&quot;Post List:&quot;, postList)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;board.go&lt;/p&gt;
&lt;pre id=&quot;code_1718639097264&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package board

import (
	&quot;dependency1/user&quot;
)

type Post struct {
	ID      int
	UserID  int
	Title   string
	Content string
}

var posts = []*Post{
	{ID: 1, UserID: 1, Title: &quot;First Post&quot;, Content: &quot;This is Alice's first post&quot;},
	{ID: 2, UserID: 2, Title: &quot;Hello World&quot;, Content: &quot;This is Bob's first post&quot;},
}

type PostInfo struct {
	*Post
	UserName string
}

func GetPostList() []*PostInfo {

	var postList []*PostInfo
	for _, post := range posts {
		// 각 게시글 작성자의 이름을 가져옴
		userName := user.GetUserNameByID(post.UserID)
		info := &amp;amp;PostInfo{Post: post, UserName: userName}
		postList = append(postList, info)
	}

	return postList
}

func GetLastPostByUserID(userID int) string {
	// 주어진 userID의 마지막 게시글 반환
	for i := len(posts) - 1; i &amp;gt;= 0; i-- {
		if posts[i].UserID == userID {
			return posts[i].Title
		}
	}
	return &quot;No posts found&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;user.go&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;go&quot; data-ke-language=&quot;go&quot;&gt;&lt;code&gt;package user

import (
	&quot;dependency1/board&quot;
)

type User struct {
	ID        int
	Name      string
	FriendIDs []int
}

var users = []*User{
	{ID: 1, Name: &quot;Alice&quot;, FriendIDs: []int{2}},
	{ID: 2, Name: &quot;Bob&quot;, FriendIDs: []int{1}},
}

type FriendInfo struct {
	*User
	LastPost string
}

func GetFriendList(userID int) []*FriendInfo {

	user := GetUserByID(userID)
	if user == nil || len(user.FriendIDs) == 0 {
		return nil
	}

	var infoList []*FriendInfo
	for _, friendID := range user.FriendIDs {
		friendUser := GetUserByID(friendID)
		// 유저의 마지막 글을 취득
		lastPost := board.GetLastPostByUserID(friendUser.ID)
		info := &amp;amp;FriendInfo{User: friendUser, LastPost: lastPost}
		infoList = append(infoList, info)
	}
	return infoList
}

func GetUserByID(userID int) *User {
	for _, user := range users {
		if user.ID == userID {
			return user
		}
	}
	return nil
}

func GetUserNameByID(userID int) string {
	user := GetUserByID(userID)
	if user == nil {
		return &quot;&quot;
	}
	return GetUserByID(userID).Name
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 실행결과&lt;/h4&gt;
&lt;pre id=&quot;code_1718639208307&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package dependency1
	imports dependency1/board
	imports dependency1/user
	imports dependency1/board: import cycle not allowed&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import cycle not allowed 에러가 발생하는걸 확인 할 수 있다&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>cycle not allowed</category>
      <category>Dependency</category>
      <category>Golang</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/9</guid>
      <comments>https://error37.tistory.com/9#entry9comment</comments>
      <pubDate>Tue, 18 Jun 2024 00:53:47 +0900</pubDate>
    </item>
    <item>
      <title>[Go] 슬라이스의 얕은 복사와 깊은 복사 (Shallow Copy and Deep Copy of Slices)</title>
      <link>https://error37.tistory.com/8</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이스의 얕은 복사와 깊은 복사에 대해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 얕은 복사&lt;/h4&gt;
&lt;pre id=&quot;code_1691072472810&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

type obj struct {
	Name string
	Age  int32
}

func main() {

	list1 := []*obj{
		{Name: &quot;A&quot;, Age: 1},
		{Name: &quot;B&quot;, Age: 2},
		{Name: &quot;C&quot;, Age: 3},
	}
	list2 := list1

	sort.Slice(list2, func(i, j int) bool {
		return list2[i].Age &amp;lt; list2[j].Age
	})

	fmt.Printf(&quot;List1 [%p]\n&quot;, list1)
	for _, item := range list1 {
		fmt.Printf(&quot;Name: %s, Age: %d [%p]\n&quot;, item.Name, item.Age, item)
	}

	fmt.Printf(&quot;List2 [%p]\n&quot;, list2)
	for _, item := range list2 {
		fmt.Printf(&quot;Name: %s, Age: %d [%p]\n&quot;, item.Name, item.Age, item)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값:&lt;/p&gt;
&lt;pre id=&quot;code_1691072691056&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List1 [0xc0000a8060]
Name: A, Age: 1 [0xc0000a8078]
Name: B, Age: 2 [0xc0000a8090]
Name: C, Age: 3 [0xc0000a80a8]
List2 [0xc0000a8060]
Name: A, Age: 1 [0xc0000a8078]
Name: B, Age: 2 [0xc0000a8090]
Name: C, Age: 3 [0xc0000a80a8]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이스가 같은 주소값(&lt;span style=&quot;color: #f3c000;&quot;&gt;&lt;b&gt;0xc0000a8060&lt;/b&gt;&lt;/span&gt;)을 가지며 원본도 같이 정렬 된 것을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 깊은 복사 (copy)&lt;/h4&gt;
&lt;pre id=&quot;code_1691072748409&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

type obj struct {
	Name string
	Age  int32
}

func main() {

	list1 := []*obj{
		{Name: &quot;C&quot;, Age: 3},
		{Name: &quot;B&quot;, Age: 2},
		{Name: &quot;A&quot;, Age: 1},
	}

	list2 := make([]*obj, len(list1))

	copy(list2, list1)

	sort.Slice(list2, func(i, j int) bool {
		return list2[i].Age &amp;lt; list2[j].Age
	})

	fmt.Printf(&quot;List1 [%p]\n&quot;, list1)
	for _, item := range list1 {
		fmt.Printf(&quot;Name: %s, Age: %d [%p]\n&quot;, item.Name, item.Age, item)
	}

	fmt.Printf(&quot;List2 [%p]\n&quot;, list2)
	for _, item := range list2 {
		fmt.Printf(&quot;Name: %s, Age: %d [%p]\n&quot;, item.Name, item.Age, item)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값:&lt;/p&gt;
&lt;pre id=&quot;code_1691072763602&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List1 [0xc00009c060]
Name: C, Age: 3 [0xc00009c078]
Name: B, Age: 2 [0xc00009c090]
Name: A, Age: 1 [0xc00009c0a8]
List2 [0xc00009c0c0]
Name: A, Age: 1 [0xc00009c0a8]
Name: B, Age: 2 [0xc00009c090]
Name: C, Age: 3 [0xc00009c078]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 슬라이스(&lt;b&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;0xc00009c060&lt;/span&gt;&lt;/b&gt;)와 다른 주소값(&lt;b&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;0xc00009c0c0&lt;/span&gt;&lt;/b&gt;)을 가진 것을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/builtin#copy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pkg.go.dev/builtin#copy&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1691073134157&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;builtin package - builtin - Go Packages&quot; data-og-description=&quot;Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to present documentation for the language's special identifiers. View Source cons&quot; data-og-host=&quot;pkg.go.dev&quot; data-og-source-url=&quot;https://pkg.go.dev/builtin#copy&quot; data-og-url=&quot;https://pkg.go.dev/builtin#copy&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/builtin#copy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pkg.go.dev/builtin#copy&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;builtin package - builtin - Go Packages&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to present documentation for the language's special identifiers. View Source cons&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pkg.go.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 깊은 복사 (append)&lt;/h4&gt;
&lt;pre id=&quot;code_1691072805120&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

type obj struct {
	Name string
	Age  int32
}

func main() {

	list1 := []*obj{
		{Name: &quot;C&quot;, Age: 3},
		{Name: &quot;B&quot;, Age: 2},
		{Name: &quot;A&quot;, Age: 1},
	}

	var list2 []*obj
	list2 = append(list2, list1...)

	sort.Slice(list2, func(i, j int) bool {
		return list2[i].Age &amp;lt; list2[j].Age
	})

	fmt.Printf(&quot;List1 [%p]\n&quot;, list1)
	for _, item := range list1 {
		fmt.Printf(&quot;Name: %s, Age: %d [%p]\n&quot;, item.Name, item.Age, item)
	}

	fmt.Printf(&quot;List2 [%p]\n&quot;, list2)
	for _, item := range list2 {
		fmt.Printf(&quot;Name: %s, Age: %d [%p]\n&quot;, item.Name, item.Age, item)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값:&lt;/p&gt;
&lt;pre id=&quot;code_1691072812044&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;List1 [0xc000116060]
Name: C, Age: 3 [0xc000116078]
Name: B, Age: 2 [0xc000116090]
Name: A, Age: 1 [0xc0001160a8]
List2 [0xc0001160c0]
Name: A, Age: 1 [0xc0001160a8]
Name: B, Age: 2 [0xc000116090]
Name: C, Age: 3 [0xc000116078]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 슬라이스(&lt;b&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;0xc000116060&lt;/span&gt;&lt;/b&gt;)와 다른 주소값(&lt;b&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;0xc0001160c0&lt;/span&gt;&lt;/b&gt;)을 가진 것을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/builtin#append&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pkg.go.dev/builtin#append&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1691073159654&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;builtin package - builtin - Go Packages&quot; data-og-description=&quot;Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to present documentation for the language's special identifiers. View Source cons&quot; data-og-host=&quot;pkg.go.dev&quot; data-og-source-url=&quot;https://pkg.go.dev/builtin#append&quot; data-og-url=&quot;https://pkg.go.dev/builtin#append&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/builtin#append&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pkg.go.dev/builtin#append&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;builtin package - builtin - Go Packages&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Package builtin provides documentation for Go's predeclared identifiers. The items documented here are not actually in package builtin but their descriptions here allow godoc to present documentation for the language's special identifiers. View Source cons&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pkg.go.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>append</category>
      <category>copy</category>
      <category>deep copy</category>
      <category>go</category>
      <category>Golang</category>
      <category>Shallow Copy</category>
      <category>Slice</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/8</guid>
      <comments>https://error37.tistory.com/8#entry8comment</comments>
      <pubDate>Thu, 3 Aug 2023 23:43:41 +0900</pubDate>
    </item>
    <item>
      <title>[Go] golang sort.Slice를 사용할때의 주의점 sort.SliceStable와의 차이점 (Important Considerations When Using golang sort.Slice and Differences from sort.SliceStable)</title>
      <link>https://error37.tistory.com/7</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sort.Slice를 사용했을때와 sort.SliceStable를 사용했을때의 결과를 비교&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. sort.Slice&lt;/h4&gt;
&lt;pre id=&quot;code_1690468799411&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

type Person struct {
	Name string
	Age  int
}

func main() {
	people := []Person{
		{&quot;Alice&quot;, 30},
		{&quot;Bob&quot;, 30},
		{&quot;Charlie&quot;, 30},
		{&quot;David&quot;, 30},
		{&quot;Eve&quot;, 30},
		{&quot;Alice&quot;, 10},
		{&quot;Bob&quot;, 10},
		{&quot;Charlie&quot;, 10},
		{&quot;David&quot;, 10},
		{&quot;Eve&quot;, 10},
		{&quot;Alice&quot;, 20},
		{&quot;Bob&quot;, 20},
		{&quot;Charlie&quot;, 20},
		{&quot;David&quot;, 20},
		{&quot;Eve&quot;, 20},
	}

	// 이름으로 정렬
	sort.Slice(people, func(i, j int) bool {
		return people[i].Name &amp;lt; people[j].Name
	})
	fmt.Println(&quot;이름으로 정렬 sort.Slice:&quot;)
	for _, p := range people {
		fmt.Printf(&quot;%s - Age: %d\n&quot;, p.Name, p.Age)
	}

	fmt.Printf(&quot;\n&quot;)

	// 나이로 정렬
	sort.SliceStable(people, func(i, j int) bool {
		return people[i].Age &amp;lt; people[j].Age
	})
	fmt.Println(&quot;나이로 정렬 sort.Slice:&quot;)
	for _, p := range people {
		fmt.Printf(&quot;%s - Age: %d\n&quot;, p.Name, p.Age)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값:&lt;/p&gt;
&lt;pre id=&quot;code_1690468819763&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;이름으로 정렬 sort.Slice:
Alice - Age: 20        
Alice - Age: 30        
Alice - Age: 10        
Bob - Age: 30
Bob - Age: 10
Bob - Age: 20
Charlie - Age: 30      
Charlie - Age: 20      
Charlie - Age: 10      
David - Age: 30        
David - Age: 10        
David - Age: 20        
Eve - Age: 10
Eve - Age: 30
Eve - Age: 20

나이로 정렬 sort.Slice:
David - Age: 10        
Alice - Age: 10        
Eve - Age: 10
Bob - Age: 10
Charlie - Age: 10
Eve - Age: 20
Bob - Age: 20
Alice - Age: 20
Charlie - Age: 20
David - Age: 20
Charlie - Age: 30
David - Age: 30
Bob - Age: 30
Eve - Age: 30
Alice - Age: 30&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퀵소트를 베이스로 하는 정렬로 슬라이스의 원래의 순서가 보장 되지않는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. sort.SliceStable&lt;/h4&gt;
&lt;pre id=&quot;code_1690469159214&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;sort&quot;
)

type Person struct {
	Name string
	Age  int
}

func main() {
	people := []Person{
		{&quot;Alice&quot;, 30},
		{&quot;Bob&quot;, 30},
		{&quot;Charlie&quot;, 30},
		{&quot;David&quot;, 30},
		{&quot;Eve&quot;, 30},
		{&quot;Alice&quot;, 10},
		{&quot;Bob&quot;, 10},
		{&quot;Charlie&quot;, 10},
		{&quot;David&quot;, 10},
		{&quot;Eve&quot;, 10},
		{&quot;Alice&quot;, 20},
		{&quot;Bob&quot;, 20},
		{&quot;Charlie&quot;, 20},
		{&quot;David&quot;, 20},
		{&quot;Eve&quot;, 20},
	}

	// 이름으로 정렬
	sort.SliceStable(people, func(i, j int) bool {
		return people[i].Name &amp;lt; people[j].Name
	})
	fmt.Println(&quot;이름으로 정렬 sort.SliceStable:&quot;)
	for _, p := range people {
		fmt.Printf(&quot;%s - Age: %d\n&quot;, p.Name, p.Age)
	}

	fmt.Printf(&quot;\n&quot;)

	// 나이로 정렬
	sort.SliceStable(people, func(i, j int) bool {
		return people[i].Age &amp;lt; people[j].Age
	})
	fmt.Println(&quot;나이로 정렬 sort.SliceStable:&quot;)
	for _, p := range people {
		fmt.Printf(&quot;%s - Age: %d\n&quot;, p.Name, p.Age)
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과값:&lt;/p&gt;
&lt;pre id=&quot;code_1690469133983&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;이름으로 정렬 sort.SliceStable:
Alice - Age: 30              
Alice - Age: 10              
Alice - Age: 20              
Bob - Age: 30                
Bob - Age: 10                
Bob - Age: 20                
Charlie - Age: 30            
Charlie - Age: 10            
Charlie - Age: 20            
David - Age: 30              
David - Age: 10              
David - Age: 20              
Eve - Age: 30                
Eve - Age: 10                
Eve - Age: 20                
                             
나이로 정렬 sort.SliceStable:
Alice - Age: 10              
Bob - Age: 10                
Charlie - Age: 10            
David - Age: 10              
Eve - Age: 10                
Alice - Age: 20              
Bob - Age: 20                
Charlie - Age: 20
David - Age: 20
Eve - Age: 20
Alice - Age: 30
Bob - Age: 30
Charlie - Age: 30
David - Age: 30
Eve - Age: 30&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래의 순서가 보장되는것을 알수있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pkg.go.dev/sort&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690469823267&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;sort package - sort - Go Packages&quot; data-og-description=&quot;ExampleMultiKeys demonstrates a technique for sorting a struct type using different sets of multiple fields in the comparison. We chain together &amp;quot;Less&amp;quot; functions, each of which compares a single field. package main import ( &amp;quot;fmt&amp;quot; &amp;quot;sort&amp;quot; ) // A Change is a &quot; data-og-host=&quot;pkg.go.dev&quot; data-og-source-url=&quot;https://pkg.go.dev/sort&quot; data-og-url=&quot;https://pkg.go.dev/sort&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://pkg.go.dev/sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pkg.go.dev/sort&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;sort package - sort - Go Packages&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;ExampleMultiKeys demonstrates a technique for sorting a struct type using different sets of multiple fields in the comparison. We chain together &quot;Less&quot; functions, each of which compares a single field. package main import ( &quot;fmt&quot; &quot;sort&quot; ) // A Change is a&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pkg.go.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&quot;&gt;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1690469490473&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&quot; data-og-description=&quot;&quot; data-og-host=&quot;cs.opensource.google&quot; data-og-source-url=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&quot; data-og-url=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;https://cs.opensource.google/go/go/+/refs/tags/go1.20.6:src/sort/slice.go&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cs.opensource.google&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://go.dev/src/sort/zsortfunc.go&quot;&gt;https://go.dev/src/sort/zsortfunc.go&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690469837380&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;- The Go Programming Language&quot; data-og-description=&quot;&quot; data-og-host=&quot;go.dev&quot; data-og-source-url=&quot;https://go.dev/src/sort/zsortfunc.go&quot; data-og-url=&quot;https://go.dev/src/sort/zsortfunc.go&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cBXw0L/hyTrPDVaOX/RmsysJldyn7OBrvH9vYhZ1/img.jpg?width=300&amp;amp;height=313&amp;amp;face=0_0_300_313&quot;&gt;&lt;a href=&quot;https://go.dev/src/sort/zsortfunc.go&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://go.dev/src/sort/zsortfunc.go&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cBXw0L/hyTrPDVaOX/RmsysJldyn7OBrvH9vYhZ1/img.jpg?width=300&amp;amp;height=313&amp;amp;face=0_0_300_313');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;- The Go Programming Language&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;go.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>[Go]</category>
      <category>go</category>
      <category>Golang</category>
      <category>Slice</category>
      <category>Sort</category>
      <category>stable</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/7</guid>
      <comments>https://error37.tistory.com/7#entry7comment</comments>
      <pubDate>Thu, 27 Jul 2023 23:56:16 +0900</pubDate>
    </item>
    <item>
      <title>[ETC]  Postman API호출에서 앞의 처리에서 취득한 정보를 포함 하고 싶을때 (When you want to include the information obtained in the previous process in the Postman API call)</title>
      <link>https://error37.tistory.com/6</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출 하고 싶은 API가 이전 처리의 결과값을 필요로 할때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 인증 정보등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pre-request Script를 사용해서 데이터를 포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;처리 순서&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;인증 API 호출&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 인증 API의 response의 token취득&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&amp;gt;&lt;span&gt; 호출 하고싶은 API의 해더값에 &lt;/span&gt;token 설정&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 호출 하고싶은 API의 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0. 테스트용 API로 이전 Golang으로 작성 서버 사용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dogfootman.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://dogfootman.com/5&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1719325932137&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Go] 고랭으로 간단한 HTTP Server 작성 (Writing a simple HTTP Server with Golang)&quot; data-og-description=&quot;개요 고랭으로 HTTP 서버 작성 1. Hello World func main() { http.HandleFunc(&amp;quot;/&amp;quot;, handler) fmt.Println(&amp;quot;Start Http Server: http://localhost:8080&amp;quot;) err := http.ListenAndServe(&amp;quot;:8080&amp;quot;, nil) if err != nil { fmt.Println(&amp;quot;Error:&amp;quot;, err) } } http.DefaultSe&quot; data-og-host=&quot;dogfootman.com&quot; data-og-source-url=&quot;https://dogfootman.com/5&quot; data-og-url=&quot;https://dogfootman.com/5&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/1XBTZ/hyWoCh251X/s3kTq0GMAZyIjzJsrl1Vrk/img.png?width=412&amp;amp;height=240&amp;amp;face=0_0_412_240,https://scrap.kakaocdn.net/dn/cbeTt4/hyWoNKFKIC/jvm2k0Zvaf9y3p5IjyL2wk/img.png?width=412&amp;amp;height=240&amp;amp;face=0_0_412_240,https://scrap.kakaocdn.net/dn/Nluoa/hyWrQ6PdtV/vBhsDCXPradoy9feYfu231/img.png?width=1276&amp;amp;height=793&amp;amp;face=0_0_1276_793&quot;&gt;&lt;a href=&quot;https://dogfootman.com/5&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://dogfootman.com/5&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/1XBTZ/hyWoCh251X/s3kTq0GMAZyIjzJsrl1Vrk/img.png?width=412&amp;amp;height=240&amp;amp;face=0_0_412_240,https://scrap.kakaocdn.net/dn/cbeTt4/hyWoNKFKIC/jvm2k0Zvaf9y3p5IjyL2wk/img.png?width=412&amp;amp;height=240&amp;amp;face=0_0_412_240,https://scrap.kakaocdn.net/dn/Nluoa/hyWrQ6PdtV/vBhsDCXPradoy9feYfu231/img.png?width=1276&amp;amp;height=793&amp;amp;face=0_0_1276_793');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Go] 고랭으로 간단한 HTTP Server 작성 (Writing a simple HTTP Server with Golang)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;개요 고랭으로 HTTP 서버 작성 1. Hello World func main() { http.HandleFunc(&quot;/&quot;, handler) fmt.Println(&quot;Start Http Server: http://localhost:8080&quot;) err := http.ListenAndServe(&quot;:8080&quot;, nil) if err != nil { fmt.Println(&quot;Error:&quot;, err) } } http.DefaultSe&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;dogfootman.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 순서&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;http://localhost:8080/login&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; response의 token취득&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; http://localhost:8080/shoplist 의 해더값으로 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; http://localhost:8080/shoplist 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. Pre-request Script 작성&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2023-07-23 234740.png&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;768&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DTaBA/btsoGiPXrIu/a5XuxjAuJTh7LQCXaYrED0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DTaBA/btsoGiPXrIu/a5XuxjAuJTh7LQCXaYrED0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DTaBA/btsoGiPXrIu/a5XuxjAuJTh7LQCXaYrED0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDTaBA%2FbtsoGiPXrIu%2Fa5XuxjAuJTh7LQCXaYrED0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1204&quot; height=&quot;768&quot; data-filename=&quot;화면 캡처 2023-07-23 234740.png&quot; data-origin-width=&quot;1204&quot; data-origin-height=&quot;768&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1690123740161&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Pre-request Script
var loginParams = {
    username: 'user1',
    password: '1234'
};
 
var requestConfig = {
    url: 'http://localhost:8080/login',
    method: 'POST',
    header: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify(loginParams)
};
 
pm.sendRequest(requestConfig, function(err, response) {
    if (err) {
        console.error(err);
    } else {
        console.log(response);
        var token = response.json().token;
        pm.request.headers.add('Bearer ' + token, 'Authorization');
    }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 도큐먼트 참조:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learning.postman.com/docs/writing-scripts/pre-request-scripts/#pre-request-scripting-example&quot;&gt;https://learning.postman.com/docs/writing-scripts/pre-request-scripts/#pre-request-scripting-example&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1690123816003&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Writing pre-request scripts | Postman Learning Center&quot; data-og-description=&quot;Writing pre-request scripts: documentation for Postman, the collaboration platform for API development. Create better APIs&amp;mdash;faster.&quot; data-og-host=&quot;learning.postman.com&quot; data-og-source-url=&quot;https://learning.postman.com/docs/writing-scripts/pre-request-scripts/#pre-request-scripting-example&quot; data-og-url=&quot;https://learning.postman.com/docs/writing-scripts/pre-request-scripts/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UQtiz/hyTo7EMUX3/XrYSq67FQQMCkYTsW2nLo0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ioT2F/hyTpdEZICi/XnLUhUfiXG0h5cSDQJNMB1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://learning.postman.com/docs/writing-scripts/pre-request-scripts/#pre-request-scripting-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learning.postman.com/docs/writing-scripts/pre-request-scripts/#pre-request-scripting-example&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UQtiz/hyTo7EMUX3/XrYSq67FQQMCkYTsW2nLo0/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/ioT2F/hyTpdEZICi/XnLUhUfiXG0h5cSDQJNMB1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Writing pre-request scripts | Postman Learning Center&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Writing pre-request scripts: documentation for Postman, the collaboration platform for API development. Create better APIs&amp;mdash;faster.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learning.postman.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. 결과 값 확인&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1625&quot; data-origin-height=&quot;1110&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cA7TfV/btsoGjnL5dl/KoNH37TFr38KuKCajDfbDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cA7TfV/btsoGjnL5dl/KoNH37TFr38KuKCajDfbDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cA7TfV/btsoGjnL5dl/KoNH37TFr38KuKCajDfbDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcA7TfV%2FbtsoGjnL5dl%2FKoNH37TFr38KuKCajDfbDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1625&quot; height=&quot;1110&quot; data-origin-width=&quot;1625&quot; data-origin-height=&quot;1110&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포스트맨: &lt;a href=&quot;https://www.postman.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.postman.com/&lt;/a&gt;&lt;/p&gt;</description>
      <category>[ETC]</category>
      <category>API</category>
      <category>Authorization</category>
      <category>Header</category>
      <category>postman</category>
      <category>pre-request script</category>
      <author>dogfootman</author>
      <guid isPermaLink="true">https://error37.tistory.com/6</guid>
      <comments>https://error37.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 23 Jul 2023 23:54:38 +0900</pubDate>
    </item>
  </channel>
</rss>