If runtime is a problem, then you could use a lookup table.  Suppose you 
have (say) 10 possible interfaces in the object: then you test those ten, 
build a 10-bit binary number from the 'ok' values, and use this as an index 
into 2^10 possible constructor functions.

You still need to compile those 2^10 functions though, each of which has a 
different struct type. I don't know if it's possible to use 'reflect' to 
build the struct type dynamically; if you can, I know you could create an 
instance of it dynamically.
https://medium.com/kokster/go-reflection-creating-objects-from-types-part-ii-composite-types-69a0e8134f20

Otherwise, I'd check for interfaces where you can safely provide a dummy 
implementation: Resetter, Validator, Pinger are good examples. For those, 
you can do what Tamás suggested: always provide an implementation in your 
wrapper object, and then if the underlying object doesn't have one, just do 
nothing and return OK. Even if you only handle those three, you'll speed up 
your compile time and runtime by a factor of 8.

On Sunday, 11 June 2023 at 20:56:14 UTC+1 Vasiliy Tolstov wrote:

> Yes, you are right. Mostly i'm worry about compile/run time. As i see on 
> my mac air m1 compilation on go 1.20 slowdown to 1-2s (i think because file 
> parsing) 
> And don't know about running time of such checks for many interface 
> implementations...
> I'm try to check in number of interfaces in descending order... But don't 
> understand how this can be optimized... May be run profile with all known 
> sql drivers and create pairs with most used combinations.... ?
>
> -- 
> Vasiliy Tolstov,
> e-mail: v.to...@selfip.ru
>
>
> На 11 июня 2023 г., 19:31:01, Brian Candler <b.ca...@pobox.com> написали:
>
>> I think the issue is that the *consumer* of this object checks whether 
>> certain methods (or rather, interfaces) are present, and behaves 
>> differently depending whether they are or not.
>>
>> There are a whole load of public interfaces defined here:
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.20.5:src/database/sql/driver/driver.go
>> And the supplied object, which the OP is trying to wrap, could implement 
>> some arbitrary combination of these interfaces.
>>
>> I think that for *some* of these interfaces, it would be OK to provide 
>> dummy implementations if there is no underlying method to call: e.g.
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.20.5:src/database/sql/sql.go;l=552-554
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.20.5:src/database/sql/sql.go;l=567-569
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.20.5:src/database/sql/sql.go;l=834-838
>>
>> But for others it's much less clear, and it may make a semantic 
>> difference whether the the object you provide implements these interfaces 
>> or not, e.g.
>>
>> https://cs.opensource.google/go/go/+/refs/tags/go1.20.5:src/database/sql/sql.go;l=1865-1867
>>
>> For these, I can't think of a better implementation that the OP's. It 
>> doesn't seem like the greatest API design though.
>>
>> On Sunday, 11 June 2023 at 08:10:01 UTC+1 Tamás Gulácsi wrote:
>>
>>> As Far as I See, you check all the combinations of methods in wideness 
>>> order.
>>> Why not have a generic wrapper struct, that is filled with the 
>>> underlying driver.Conn's methods, 
>>> and use that if not nil, but use the generic implementation if not.
>>>
>>> Like
>>> ```
>>> type wrappedConn struct {
>>>   driver.Conn
>>>   queryContext func(...)
>>> }
>>> func (wc wrappedConn) QueryContext(...) ... {
>>>   if wc.queryContext != nil { return wc.queryContext(...) }
>>>   return wc.Conn.Query(...)
>>> }
>>> ```
>>>
>>> This way you only have to check for each method on driver.Conn, and fill 
>>> the wrappedConn's functions as they axist/not.
>>>
>>> Vasiliy Tolstov a következőt írta (2023. június 10., szombat, 12:16:34 
>>> UTC+2):
>>>
>>>> I have sql driver that wraps original driver.Driver, to be able to work 
>>>> with drivers that not have ExecerContext or QuerierContext i need to 
>>>> return 
>>>> wrapped to that supports only needed interfaces.
>>>> I'm to want to write all cases via handmade switch case and write 
>>>> generator that creates full combo list of methods and generate interfaces 
>>>> for this methods.
>>>> But this brings file that contains 20K lines 
>>>> https://git.unistack.org/unistack-org/micro-wrapper-sql/src/branch/master/wrap_gen.go
>>>> Does it possible to have smaller code that provides the same effect?
>>>> Or I'm miss something?
>>>>
>>>> -- 
>>>> Vasiliy Tolstov,
>>>> e-mail: v.to...@selfip.ru
>>>>
>>> -- 
>> 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...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/4dc775df-6627-4134-8b32-e9f659e48831n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/4dc775df-6627-4134-8b32-e9f659e48831n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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/ada26a7e-4c21-412d-9e81-ee6fd72a8513n%40googlegroups.com.

Reply via email to