Skip to content

Commit abe03ab

Browse files
committed
Add Channel{T}(f::Function) constructors.
The Channel constructors that do and don't create a Task are currently written in different styles: - The non-Task constructor takes a Type {T} as a type parameter, and the size as a positional argument. - `Channel{Int}(Inf)` - `Channel(0)` - The Task constructor takes a Function, but the size and type are keyword arguments: - `Channel(c->put!(c,0), ctype=Int, csize=0)` - `Channel(ctype=Int, csize=0, taskref=t) do c; put!(c,0); end` This commit adds convenience methods to the Task-creating constructor, allowing you to specify the Type and/or size as in the non-Task constructor: - `Channel{Char}(1) do c; put!(c, 'a'); end` - `Channel{Char}(csize=2, taskref=t) do c; put!(c, 'a'); end` --- Also adds tests for the existing Task-creating constructors, which weren't explicitly tested before.
1 parent faefe2a commit abe03ab

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

base/channels.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ Hello
9595
julia> istaskdone(taskref[])
9696
true
9797
```
98+
99+
Other constructors:
100+
* `Channel{T}(func::Function, sz=0)`
101+
* `Channel{T}(func::Function; csize=0, taskref=nothing)`
102+
103+
```jldoctest
104+
julia> chnl = Channel{Char}(1) do ch
105+
for c in "hello world"
106+
put!(ch, c)
107+
end
108+
end
109+
>> Channel{Char}(sz_max:1,sz_curr:1)
110+
111+
julia> String(collect(chnl))
112+
>> "hello world"
113+
```
98114
"""
99115
function Channel(func::Function; ctype=Any, csize=0, taskref=nothing)
100116
chnl = Channel{ctype}(csize)
@@ -105,6 +121,12 @@ function Channel(func::Function; ctype=Any, csize=0, taskref=nothing)
105121
isa(taskref, Ref{Task}) && (taskref[] = task)
106122
return chnl
107123
end
124+
function Channel{T}(f::Function, sz=0) where T
125+
return Channel(f, csize=sz, ctype=T)
126+
end
127+
function Channel{T}(f::Function; csize=0, taskref=nothing) where T
128+
return Channel(f, csize=csize, ctype=T, taskref=taskref)
129+
end
108130

109131

110132
closed_exception() = InvalidStateException("Channel is closed.", :closed)

test/channels.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,32 @@ end
3636
@test_throws InexactError Channel(1.5)
3737
end
3838

39+
@testset "Task constructors" begin
40+
c = Channel(ctype=Float32, csize=2) do c; map(i->put!(c,i), 1:100); end
41+
@test eltype(c) == Float32
42+
@test c.sz_max == 2
43+
@test isopen(c)
44+
@test collect(c) == 1:100
45+
46+
c = Channel{Int}() do c; map(i->put!(c,i), 1:100); end
47+
@test eltype(c) == Int
48+
@test c.sz_max == 0
49+
@test collect(c) == 1:100
50+
51+
c = Channel{Int}(Inf) do c; put!(c,1); end
52+
@test eltype(c) == Int
53+
@test c.sz_max == typemax(Int)
54+
55+
taskref = Ref{Task}()
56+
c = Channel{Int}(csize=0, taskref=taskref) do c; put!(c, 0); end
57+
@test eltype(c) == Int
58+
@test c.sz_max == 0
59+
@test istaskstarted(taskref[])
60+
@test !istaskdone(taskref[])
61+
take!(c); yield()
62+
@test istaskdone(taskref[])
63+
end
64+
3965
@testset "multiple concurrent put!/take! on a channel for different sizes" begin
4066
function testcpt(sz)
4167
c = Channel{Int}(sz)

0 commit comments

Comments
 (0)