Created
May 13, 2025 12:16
-
-
Save sithumonline/9355e8fad5051ed2d438ca1b56860940 to your computer and use it in GitHub Desktop.
Value va Pointer v1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "fmt" | |
| "sync" | |
| ) | |
| // Counter holds a simple integer. | |
| type Counter struct { | |
| N int | |
| } | |
| // IncValue is a VALUE receiver: it works on a COPY. | |
| func (c Counter) IncValue() { | |
| c.N++ | |
| fmt.Println(" [inside IncValue] c.N =", c.N) | |
| } | |
| // IncPtr is a POINTER receiver: it mutates the original. | |
| func (c *Counter) IncPtr() { | |
| c.N++ | |
| fmt.Println(" [inside IncPtr] c.N =", c.N) | |
| } | |
| /***********/ | |
| type SafeMap struct { | |
| mu sync.Mutex | |
| m map[int]int | |
| } | |
| // LockMap and UnlockMap use VALUE receivers — they lock/unlock a COPY of mu! | |
| func (sm *SafeMap) LockMap() { | |
| sm.mu.Lock() | |
| } | |
| func (sm *SafeMap) UnlockMap() { | |
| sm.mu.Unlock() | |
| } | |
| // Store wraps a map write in those (ineffective) locks | |
| func (sm SafeMap) Store(key, value int) { | |
| sm.LockMap() | |
| sm.m[key] = value | |
| sm.UnlockMap() | |
| } | |
| /***********/ | |
| // S has one value‐receiver and one pointer‐receiver method. | |
| type S struct{ V int } | |
| // Value receiver: belongs to both S and *S. | |
| func (s S) Val() { | |
| fmt.Println("Called Val(), V =", s.V) | |
| } | |
| // Pointer receiver: belongs only to *S. | |
| func (s *S) Ptr() { | |
| fmt.Println("Called Ptr(), V =", s.V) | |
| } | |
| // Interfaces for each method. | |
| type IVal interface{ Val() } | |
| type IPtr interface{ Ptr() } | |
| func main() { | |
| fmt.Println("== Working with value instance ==") | |
| c := Counter{N: 0} | |
| fmt.Println("Start: c.N =", c.N) | |
| // 1) Call the value-receiver method | |
| c.IncValue() | |
| fmt.Println("After IncValue(): c.N =", c.N) | |
| // 2) Call the pointer-receiver method | |
| c.IncPtr() | |
| fmt.Println("After IncPtr(): c.N =", c.N) | |
| /***********/ | |
| fmt.Println("\n== Working with pointer instance ==") | |
| sm := SafeMap{m: make(map[int]int)} | |
| var wg sync.WaitGroup | |
| // crank up the concurrency | |
| for i := 0; i < 10; i++ { // change to 10_000 for a real test; it'll be panic due to deadlock | |
| wg.Add(1) | |
| go func(i int) { | |
| defer wg.Done() | |
| sm.Store(i, i) | |
| fmt.Println("storing", i) | |
| }(i) | |
| } | |
| wg.Wait() | |
| fmt.Println("finished storing", len(sm.m), "entries") | |
| /***********/ | |
| fmt.Println("\n== Working with value and pointer receivers ==") | |
| s := S{V: 42} | |
| ps := &s | |
| // IVal can be satisfied by S _or_ *S: | |
| var iv1 IVal = s | |
| iv1.Val() // OK: prints "Called Val(), V = 42" | |
| var iv2 IVal = ps | |
| iv2.Val() // OK: also prints "Called Val(), V = 42" | |
| // IPtr can only be satisfied by *S: | |
| var ip IPtr = ps | |
| ip.Ptr() // OK: prints "Called Ptr(), V = 42" | |
| // Uncommenting the next line causes a compile‐time error: | |
| //var ip2 IPtr = s | |
| //ip2.Ptr() // ERROR: cannot use s (type S) as type IPtr in assignment: | |
| // → cannot use s (type S) as type IPtr in assignment: | |
| // S does not implement IPtr (Ptr method has pointer receiver) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment