diff --git a/base/dict.jl b/base/dict.jl index 33e78f4639666..045fb8b23d0e8 100644 --- a/base/dict.jl +++ b/base/dict.jl @@ -529,6 +529,21 @@ function get!{K,V}(h::Dict{K,V}, key0, default) return v end +function get!{K,V}(default::Function, h::Dict{K,V}, key0) + key = convert(K,key0) + if !isequal(key,key0) + error(key0, " is not a valid key for type ", K) + end + + index = ht_keyindex2(h, key) + + index > 0 && return h.vals[index] + + v = convert(V, default()) + _setindex!(h, v, key, -index) + return v +end + function getindex{K,V}(h::Dict{K,V}, key) index = ht_keyindex(h, key) return (index<0) ? throw(KeyError(key)) : h.vals[index]::V diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index a4a360dc354fb..3ed6541a49754 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -727,6 +727,21 @@ Given a dictionary ``D``, the syntax ``D[x]`` returns the value of key ``x`` (if Return the value stored for the given key, or the given default value if no mapping for the key is present. +.. function:: get!(collection, key, default) + + Return the value stored for the given key, or if no mapping for the key is present, store ``key => default``, and return ``default``. + +.. function:: get!(f::Function, collection, key) + + Return the value stored for the given key, or if no mapping for the key is present, store ``key => f()``, and return ``f()``. + + This is intended to be called using ``do`` block syntax:: + + get!(dict, key) do + # default value calculated here + time() + end + .. function:: getkey(collection, key, default) Return the key matching argument ``key`` if one exists in ``collection``, otherwise return ``default``. diff --git a/test/collections.jl b/test/collections.jl index 30393bd4be25b..f7f1872d5f4bc 100644 --- a/test/collections.jl +++ b/test/collections.jl @@ -154,7 +154,10 @@ let def = {} @test get!(d, 8, 5) == 19 @test get!(d, 19, 2) == 2 - @test d == {8=>19, 19=>2} + @test get!(d, 42) do + int(e^2) + end == 7 + @test d == {8=>19, 19=>2, 42=>7} end # issue #2540