-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: Go2: allow assigning chan chan struct{}
to <-chan chan<- struct{}
(nested channel direction auto-conversion in general)
#21577
Comments
chan chan struct{}
to <-chan -chan<- struct{}
(nested channel direction auto-conversion in general)chan chan struct{}
to <-chan chan<- struct{}
(nested channel direction auto-conversion in general)
chan chan struct{}
to <-chan chan<- struct{}
(nested channel direction auto-conversion in general)chan chan struct{}
to <-chan chan<- struct{}
(nested channel direction auto-conversion in general)
Marking as Go2 since we are not doing language changes right now. |
I want to make this proposal for Go 1. This is a tiny, completely backwards compatible change that is just removing an unwise, unnecessary and artificial limitation. |
I'm sorry, I mistyped my comment (I've edited it to correct it). We are not doing language changes right now. This change looks tiny, but I think it's more complicated than it seems. We have to decide how to handle cases like
Maybe it's simple but in effect it's similar to assignment rules for the |
I was thinking about a recursive assignability definition right now, but that comes with complications, because however I tried to define it, it enabled things like this: var a []int
var b []interface{}
b = a // would pass, bad thing But, the problem is solvable in an easy way, although one might argue that it's a little ugly. The thing is to redefine type identity of channels from this:
To this:
This change in the spec would allow what I'm asking for and would prevent things like assigning It's possible this change has some gotchas, but I haven't come up with any yet. |
With the above change, this line could be removed from the spec:
|
I just realized that my example/use-case is actually trivially solvable by rewriting this: package main
func f(cancel <-chan chan<- struct{}) {
confirm := <-cancel
close(confirm)
}
func main() {
cancel := make(chan chan struct{})
go f(cancel) // compile error
confirm := make(chan struct{})
cancel <- confirm
<-confirm
} to this package main
func f(cancel <-chan chan<- struct{}) {
confirm := <-cancel
close(confirm)
}
func main() {
cancel := make(chan chan<- struct{}) // the arrow right here
go f(cancel) // passes just fine
confirm := make(chan struct{})
cancel <- confirm
<-confirm
} However, this still might be useful in more complicated scenarios. |
This proposal assumes that the in-memory representation for |
@bcmills That's a fair point and I actually no longer feel like this proposal is a good idea. First, I've been able to solve my problem as I described above. Second, all situation imaginable where this would be useful seem like bad code with duplications. |
Hello!
This surprised me recently. This is perfectly possible
Assigning a bi-directional channel to a uni-directional is done without any conversions. And it makes complete sense, there is nothing preventing it.
However, it is not possible when a channel is inside another structure. Examples:
Note that a and b have anonymous types. The conversion is impossible, although nothing is preventing it.
My specific use-case is a cancellation-confirmation channel. I have a goroutine that I want to cancel and I want that goroutine to report the successful cancellation back. Thus, I pass it a channel of channels. The cancellation signal is a confirmation channel. After a successful cancelation, the goroutine sends a confirmation signal. Like this:
Now, I want to restrict the channel directions on the cancelation channel passed to f (f can't cancel itself and so on). So, logically, I change the
f
's signature like this:Playground here: https://play.golang.org/p/YTcUnisWHg .
But, this doesn't compile, giving:
There is no reason why this wouldn't compile. It's just that compiler doesn't auto-"convert" (convert is in quotes, since this is merely a compile time feature, it doesn't really affect any compiled code, or runtime behaviour) channel directions structurally recursively.
I propose it should do it recursively.
Thanks,
Michal Štrba
EDIT: fixed playground link
The text was updated successfully, but these errors were encountered: