goio
goio copied to clipboard
Discussion on how to use
1、First I have a struct
type KVBase struct {
Index int64 `json:"index"`
Enable bool `json:"enable"`
Key string `json:"key"`
Value string `json:"value"`
}
2、If I have an array of this struct, I hope to do some processing on it and get a map, I can write like this
var kvs []KVBase
m := make(map[string]string)
sort.Slice(kvs, func(i, j int) bool {
return kvs[i].Index < kvs[j].Index
})
for _, kv := range kvs {
if !kv.Enable {
continue
}
m[kv.Key] = kv.Value
}
3、If the same structure is put into java, I can write it like this, and the efficiency should be similar to the above, I think it's elegant
@Data
class KVBase {
private int index;
private String key;
private String value;
private boolean enable;
}
KVBase[] kvs = {};
Map<String, String> m = Stream.of(kvs)
.sorted(Comparator.comparing(kv -> kv.index < kv.index))
.filter(kv -> !kv.enable)
.map(kv -> Pair.of(kv.key, kv.value))
.collect(Collectors.toMap(Pair::getKey, Pair::getValue));
4、I personally thought this was elegant so I was looking to see if there was something like this in Go, until I discovered this framework. I looked at the examples and found that the methods in them were not only very similar, so I tried to write them in Java.But unfortunately I just got the following code
sort.Slice(headers, func(i, j int) bool {
return headers[i].Index < headers[j].Index
})
stream_1 := stream.FromSlice(headers)
stream_1 = stream.Filter(stream_1, func(h header) bool {
if h.Enable {
return true
}
return false
})
stream_2 := stream.Map(stream_1, func(h header) fun.Pair[string, string] {
f := fun.Pair[string, string]{
V1: h.Key,
V2: h.Value,
}
return f
})
m := make(map[string]string)
stream.Collect(stream_2, func(f fun.Pair[string, string]) error {
m[f.V1] = f.V2
return nil
})
So I want to ask:
- Is this framework capable of doing the same as java? If so, could you please provide examples or where they appear?
- If not, is there a serious mistake in my writing method? How can I write it so that it can be almost as efficient as the first writing method? Please give an example.
Hey, @wayddmldbzz,
Thank you for your interest in this framework. Your stream-based Java-example looks nice.
The Java DSL uses an important language feature. Stream
interface approximately looks like this:
interface Stream<T> {
<R> map(Function<T, R>)
...
}
Unfortunately, to my knowledge Go does not support this kind of interfaces. The only similar feature that I was able to find was to use plain functions that can take generic parameters:
func Map[T, R](Stream[T], func(T)R)
Hence, the nice Java-style DSL seems to be infeasible in the current version of Go.
Your code looks almost right. In order to make it nicer, I would make a small refactoring:
func isEnabled(h KVBase) bool {
return h.Enabled
}
func toKeyValuePair(h KVBase) fun.Pair[string, string] {
return fun.NewPair(h.Key, h.Value)
}
func Foo() {
sort.Slice(headers, func(i, j int) bool {
return headers[i].Index < headers[j].Index
})
headersStream := stream.FromSlice(headers)
enabled := stream.Filter(headersStream, isEnabled)
keyValues := stream.Map(enabled, toKeyValuePair)
m := make(map[string]string)
preserveKeyValue := func(f fun.Pair[string, string]) {
m[f.V1] = f.V2
}
delayedStreamExecution := stream.ForEach(keyValues, preserveKeyValue)
_, err := io.UnsafeRunSync(delayedStreamExecution)
...
}
Note that stream is lazy and needs UnsafeRunSync
at the end.