-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: make go
statement return a chan
#26287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This seems like making the language more complex so that one may avoid writing two lines of simple code from time to time. I don't think that's a good idea. Also note that, in plenty of occasions, you want to communicate in a different manner. Perhaps there's an error to pass back to the main goroutine. Perhaps you're firing lots of goroutines, so a |
go
statement return a chan
.go
statement return a chan
In cases where you fire a dynamic amount of goroutines a sync.WaitGroup is absolutely better - especially when you employ different means of communication. Naturally this depends on how you feed the results back and whether you need to wrap the function you're calling or not and whether you need the results back in some order or not, how many sends you have per channel...
Yep. This wouldn't address the complexity of having multiple goroutines with multiple error conditions that require cancellation of other goroutines and careful closing of channels etc. to not either deadlock on errors or panic on errors. There's a lot of caveats there
which will deadlock on error for a number of different reasons (in the write to the errChan if not properly buffered, in the write to inputs because the consumer(s) are not reading anymore). This proposal wouldn't address any "issues" (well, they're not really issues, writing parallel code just requires careful thought) that have to do with complexity of gouroutines and channels. It's just a "syntactic" shortcut for a few things. I.e.
which could directly be replaced with
It saves two to three lines of code here and there and saves writing a wrapper function here and there and it looks "cleaner" to me because it's immediately obvious that you're doing a spawn&wait. Edit: I might come up with better real world examples but it's essentially the same deal: it just simplifies some constructs by a few lines. |
As @mvdan says, this is just a few lines of code. And it's not an especially common case--it arises, certainly, but not all the time. It's not worth making the language more complicated to save a few lines of code in a case that is not common. |
Sorry to see this one get closed! I am looking for just this functionality. It seems like the most important part has been missed, in that it would allow you to sync with a goroutine without requiring the launched goroutine to explicitly know it needs to sync with the launcher. I'm looking for an elegant way to do this for testing a CLI. I'd like to pass in a function that'll run in a goroutine and interact with a virtual console I'm creating. I want to launch the goroutine, which will block at various points based on the console output using go-expect. Once the goroutine is launched, I want to start the console up and the block until the launched goroutine is complete. I'd like the launched goroutine to not have to interact with a specific channel, but just to do it's thing... I just have no way to wait for the goroutine to finish without the goroutine explicitly interacting with a shared channel.
I'm sure there are plenty of ways to get this done, but it seems like if Go supports functions being passed around and executed, one should be able to get some state from the running function. Even just having a return value with a |
@berniedurfee-ge Do you know about |
I do, but I think that's the same issue, the launched function needs to have a reference to that waitgroup and needs to explicitly call wg.done() to notify the caller that it's finished. What I'd like to have is a way for the launcher of a goroutine to be able to wait for the launched goroutine to return without the launched goroutine to even know it's been launched as a goroutine. Something like channel that can receive a message when a goroutine finishes or something more explicit like https://golang.org/pkg/os/exec/#Cmd.Wait, but for a goroutine. |
I write code using wg.Add(1)
go func() {
defer wg.Done()
doTheTheing()
}()
...
wg.Wait() The real code of the goroutine doesn't have to know about the |
@ianlancetaylor Thanks! This is exactly where I landed, though I used a channel.
|
Suggestion
When used as a value the
go
statement could return a channel that is automatically closed when the goroutine returns and returns the return value of the function.Instead of
this would allow a simplification to
Other use cases
In a select
As arguments to other functions
For "async" work
This isn't full "true async" support since the call to doOtherWork blocks until both
results are available regardless of which result doOtherWork needs first but it comes
close for most use cases to a system that has "true async" support.
If there are plans to add "true async" support to the language this proposal would probably be redundant.
(The term "true async" here I use to refer to languages where there's no notable difference for the programmer in terms of whether something is async or not and nothing blocks until the result is actually needed).
Remarks
Cases when the function has a return type of for example
(int, error)
are still a problem. Might be less of a problem if there were multi-value channels (such aschan (int, error)
) not sure if such a proposal already exists and what the state on that is.It can be implemented with helper functions but requires working with
interface{}
for it to be generic.Easy alternative is using a spawn function:
The text was updated successfully, but these errors were encountered: