Preallocate an array with the element type, which is unknow before running?

In some situation, I need to preallocate an array, but the element type is not fixed until running.
Here is a example:

struct Test{T}
    a::T #some function
    n::Int
end

function (test::Test)(data::AbstractArray)
    res=Array{Float64}(undef,size(data))
    for i = 1 : size(data,1)
        start_i = i < test.n ? 1 : i - test.n + 1
        res[i]=test.a(data[start_i : i])
    end
    res
end

test1=Test(mean,5)
test2=Test(cov,5)

data1=randn(10)
10-element Vector{Float64}:
 -0.59236859043663
  1.1109575552202715
  0.7317098287660007
  0.34954035787008153
 -0.8971785589659997
  0.10284823337677379
  1.1058285220935977
  0.35331116031440585
  1.3334401397129447
 -0.4044996149070988

data1=randn(10,3)

test1(data1) can running well, but test2(data2) not. Because cov return Matrix. I have to define this:

function (test::Test{typeof(cov),Int})(data::AbstractArray)
    res=Array{Matrix}(undef,size(data))
    for i = 1 : size(data,1)
        start_i = i < test.n ? 1 : i - test.n + 1
        res[i]=test.a(data[start_i : i])
    end
    res
end

But this would generate repeated code. So how can I avoid this?

You can make use of map instead of the manual loop, that way you do not have to preallocate yourself.

For example:

function (test::Test)(data::AbstractArray)
    map(1 : size(data,1)) do i
        start_i = i < test.n ? 1 : i - test.n + 1
        test.a(data[start_i : i])
    end
end

If you really want to use the loop, you could call the function on the first element of the array and use the type of the result to allocate the array. Then you’d loop over the second to last elements. Using map is much more convenient and cleaner though.