Для скалярных (т.е. не похожих на массивы) необязательных аргументов я бы использовал этот шаблон:
[<ExcelFunction(Category= "Test", Description= "Test optional arguments.")>]
let test_test1 ([<ExcelArgument(Description= "Optional. This is a double. Default is 42.0.")>] arg1 : obj) : double =
match arg1 with
| :? ExcelMissing -> 42.0 // the argument was missing
| :? double as d -> d // the argument was a double
| _ -> -1.0 // otherwise
Я не уверен, является ли этот код "идиоматическим" в Excel-Dna / F #, но, похоже,"работать".
Однако я не уверен, как действовать для необязательных аргументов, подобных массиву.Например:
[<ExcelFunction(Category= "Test", Description= "Test optional arguments.")>]
let test_test2 ([<ExcelArgument(Description= "Optional. This is a double. Default is [42, 42].")>] arg1 : obj[]) : double[] =
match arg1.[0] with
| :? ExcelMissing -> [42.0; 42.0] |> List.toArray // the argument was missing OR it was an empty array
| :? double as d -> arg1 |> castToDouble // the argument was an array and its first argument was a double
| _ -> Array.empty // otherwise
Вышеприведенное, похоже, работает для большинства случаев, но не позволяет правильно обрабатывать крайние случаи: например, если arg1 - пустой массив.(castToDouble
является пользовательской obj[] -> double[]
функцией преобразования)
Каков будет правильный / идиоматический способ обработки необязательных двойных массивов в F # / Excel-Dna и как я могу затем переписатьtest_test2?
=========== РЕДАКТИРОВАТЬ ===
Следуя совету Говерта, я попробовал следующее:
[<ExcelFunction(Category= "Test", Description= "Test optional arguments.")>]
let test_test3 ([<ExcelArgument(Description= "Optional. This is a double. Default is [42, 42].")>] arg1 : obj) : double[] =
match arg1 with
| :? (double[]) as ds -> [1.0; 2.0] |> List.toArray // the argument was a array of double elements
| :? ExcelMissing -> [42.0; 42.0] |> List.toArray // the argument was missing OR it was an empty array
| _ -> Array.empty // otherwise
...но, к сожалению, я получаю вывод #NUM!
, когда передаю массив значений типа double (или чего-либо еще).Только когда я ничего не передаю, я правильно получаю массив [42.0, 42.0].