I agree, and there's a clear benefit that it's harder to dereference a nil 
interface than a nil pointer, when that interface has no methods.  The 
problem is that statically it doesn't tell you anything about the possible 
contained type.

In comparison, a pointer tells you exactly the type contained, but it must 
be exactly one type, and there's always a risk of accidentally deferencing 
a nil pointer. 

If one day, generics type-constraint interfaces could be used as regular 
interface types, that would be powerful: you could have a variable of type 
"interface { float64 | Status }" and know for sure that the value *must* be 
either nil, float64 or Status. Furthermore, you wouldn't be able to use the 
contained value without an explicit type assertion.

On Wednesday, 6 April 2022 at 01:10:23 UTC+1 sam.a....@gmail.com wrote:

> 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/4019e780-8fca-4e5b-88e3-f9fdcd1d32a8n%40googlegroups.com.

Reply via email to