Modifying the capacity of a slice won't prevent someone from using unsafe to read the memory outside the region you've given them, but it does prevent accidents within "safe" go code (poor use of append + the like) from messing up your data, and makes errors in other's code more obvious.
Ignoring malicious/unsafe code, where the best way to protect your data is to make copies, by adjusting the capacity of a slice you can avoid problems like:
http://play.golang.org/p/WjkNlKM1mi
I have created two functions to do what you're looking for in
https://github.com/cookieo9/go-misc/blob/master/slice/cap.go
The first "ShrinkCapacity()", takes an array pointer and allows you to shrink (but not grow) the cap value *in-place*. The second "HardSlice" performs a regular slice operation, but after completing sets cap to len so the resulting slice can't be expanded into by append. Both functions are generic in that they can (by using reflection) take any type of slice, but bad input will result in runtime panics instead of compile-time errors, and they will have slightly worse performance than a built-in solution or writing your own unsafe code.
eg:
base := make([]int, 10)
// Faster (less reflection)
a := base[:5]
slice.ShrinkCapacity(&a,len(a))
// One-Line but with annoying type assertion
b := slice.HardSlice(base,5,10).([]int)