I get what you're saying, and for what it's worth, you're absolutely 
correct. Something like above is a set of tradeoffs, and I guess all I can 
assert is that it works for me. I do think it's a good design, given Go's 
lack of a None<T> type to enforce well-defined behavior on a nil pointer 
dereference, but it's an example of a well-designed API from the days 
before generics, which safely respects nil/null values in the appropriate 
context.

For most of my use of the model, the types offered by the pgtype pacakge 
are A. total overkill, and B. just an intermediate type to hold a value 
between two boundaries that do understand null values, such as bridging an 
RPC frontend and a SQL backend.

If anything, it proves that Generics do simplify codebases, and that 
well-defined, graceful null/nil handling is worth the effort.
On Tuesday, April 5, 2022 at 5:13:04 AM UTC-5 Brian Candler wrote:

> I did look at the code briefly.  The main thing I noticed was that the 
> return type of float8.Get() was an interface{} - so it's up to the caller 
> to check at runtime whether the value is nil, a float64, or a Status.
>
> So you're right, it's not that they are compile-time unsafe, but rather 
> that you have to write type matching code at each use site. Within a given 
> switch branch, it's safe.
>
> On Tuesday, 5 April 2022 at 07:29:09 UTC+1 sam.a....@gmail.com wrote:
>
>> Uh, you should check the code: 
>> github.com/jackc/pgtype/blob/master/float8.go If you know what you have 
>> and what you're dealing with, and if you actually check the error result, 
>> you do get safety. If you don't know what you've got, or if you're 
>> iterating through the values, then you end up hitting the sad, sad, 
>> reflective path...for now.
>> On Saturday, April 2, 2022 at 4:37:36 AM UTC-5 Brian Candler wrote:
>>
>>> Correct repository path is: https://github.com/jackc/pgtype
>>>
>>> Interesting.  These structs generally contain a Status value as well:
>>>
>>> type Int8 struct {
>>>    Int int64
>>>    Status Status
>>> }
>>>
>>> where pgtype.go has:
>>>
>>> type Status byte
>>>
>>> const (
>>>    Undefined Status = iota
>>>    Null
>>>    Present
>>> )
>>>
>>> They also have Set() and Get() methods, although these are not 
>>> compiled-time type safe as they accept and return interface{}
>>>
>>> On Friday, 1 April 2022 at 17:40:42 UTC+1 sam.a....@gmail.com wrote:
>>>
>>>>
>>>> Thanks for clarifying that, @Brian. Yeah. It took a bit to warm up to 
>>>> that approach, but the github.com/jackc/pgtypes convinced me that the 
>>>> results were worth it. The benefits:  A, package interpretation methods 
>>>> with a piece of data, B, lazily valuate data when needed, and C, gain 
>>>> introspective capability specific to the type and not using reflect
>>>> On Friday, April 1, 2022 at 4:47:32 AM UTC-5 Brian Candler wrote:
>>>>
>>>>> That wasn't literal code with anglebrackets - you're supposed to fill 
>>>>> that in yourself.  I think he meant something like:
>>>>>
>>>>> type fooString struct{ string }
>>>>>
>>>>> https://go.dev/play/p/4Q94xMZDciV
>>>>>
>>>>> What this is doing is *embedding* a string value into a struct; if you 
>>>>> have not come across type embedding before then Google for the details.
>>>>>
>>>>> You still cannot use one of these types transparently as a string, but 
>>>>> you can use
>>>>>     x.string
>>>>> instead of
>>>>>     string(x)
>>>>> to extract the value.
>>>>>
>>>>> On Friday, 1 April 2022 at 06:48:04 UTC+1 yan.z...@gmail.com wrote:
>>>>>
>>>>>> Hi Sam! Your solution does not seem to work:
>>>>>>
>>>>>> package main
>>>>>>
>>>>>> import(
>>>>>>     "fmt"
>>>>>>     "strconv"
>>>>>>     )
>>>>>>
>>>>>> type <Purpose> String struct{string}
>>>>>>
>>>>>> func (s String) print(){
>>>>>>     fmt.Println(s)
>>>>>> }
>>>>>>
>>>>>> func main() {
>>>>>>    var a String ="hello, world\n"
>>>>>>
>>>>>>    a.print()
>>>>>>    
>>>>>>    fmt.Println(strconv.ParseInt("78",10, 64))
>>>>>>    
>>>>>>    var x String ="452"
>>>>>>
>>>>>>    n, _ := strconv.ParseInt(x, 10, 64)
>>>>>> }
>>>>>>
>>>>>> 在2022年3月26日星期六 UTC+8 06:41:15<sam.a....@gmail.com> 写道:
>>>>>>
>>>>>>>
>>>>>>> My workaround like is something like `type <Purpose>String 
>>>>>>> struct{string}. It can be reasonably treated as a string for most cases 
>>>>>>> in 
>>>>>>> which as string is needed, and it lets you convert back conveniently 
>>>>>>> from 
>>>>>>> any scope in which it's reasonable for your program to know the 
>>>>>>> difference.
>>>>>>> On Friday, March 18, 2022 at 12:46:34 AM UTC-5 Henry wrote:
>>>>>>>
>>>>>>>> My own preference is to have a small number of methods and put the 
>>>>>>>> general functionalities into functions. By putting the general 
>>>>>>>> functionalities into functions, you allow code reuse. In 
>>>>>>>> object-oriented 
>>>>>>>> programming, you normally attach as many functionalities as possible 
>>>>>>>> to 
>>>>>>>> their corresponding types and achieve code reuse via inheritance. 
>>>>>>>> Since Go 
>>>>>>>> does not have inheritance, you can achieve a similar effect with 
>>>>>>>> standalone 
>>>>>>>> functions. 
>>>>>>>>
>>>>>>>> On Friday, March 18, 2022 at 11:26:51 AM UTC+7 Ian Lance Taylor 
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> On Thu, Mar 17, 2022 at 7:17 PM Zhaoxun Yan <yan.z...@gmail.com> 
>>>>>>>>> wrote: 
>>>>>>>>> > 
>>>>>>>>> > I just came across this taboo in golang - new methods cannot be 
>>>>>>>>> added to an existing type: 
>>>>>>>>>
>>>>>>>>> Yes. If we didn't have this prohibition, then the set of 
>>>>>>>>> interfaces 
>>>>>>>>> satisfied by a type would depend on which package was using the 
>>>>>>>>> type. 
>>>>>>>>>
>>>>>>>>> See the discussion at https://go.dev/issue/21401. 
>>>>>>>>>
>>>>>>>>> Ian 
>>>>>>>>>
>>>>>>>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/319f930e-bb69-4b06-bf94-b5bd8ef73a09n%40googlegroups.com.

Reply via email to