Я прочитал f-equivalent-of-cs-out, но все же я не могу заставить его работать для моего случая (самое простое решение/синтаксис).
У меня есть этот метод в проекте С#:
//<Project Sdk="Microsoft.NET.Sdk">
//<TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks>
public static void ABC(out byte[] a, out byte[] b, byte[] c)
{
var aaa = new byte[10];
var bbb = new byte[10];
a = aaa;
b = bbb;
}
Теперь я хочу использовать его в проекте F#: я использую FSharp.Core 4.7.2
(* <Project Sdk="Microsoft.NET.Sdk">
<TargetFrameworks>netcoreapp3.1;netstandard2.0</TargetFrameworks> *)
let a,b = ABC(c)
Я имитирую синтаксис TryParse
, и это компилируется без ошибок:
let success, number = System.Int32.TryParse("0")
Компилятор на моем вызове ABC(c)
жалуется на то, что подпись запрашивает 3 параметра, а не 1.
По сравнению с TryParse
я вижу 2 отличия:
- Не возвращает
void
- Он использует объекты массива
Компилятор принимает такой синтаксис:
let a = Array.empty<byte>
let b = Array.empty<byte>
ABC(ref a, ref b, c)
но:
- Я думаю, что здесь неправильно использовать
ref
, не таким образом (потому чтоa
иb
не изменяемы) - Я хотел бы использовать чистый синтаксис, похожий на
TryParse
, и Я ХОЧУ знать, почему он здесь не работает
Я могу изменить код проекта C#, но замена всех параметров out
в этом проекте будет вторым шагом и, возможно, новым вопросом, если у меня возникнут трудности или сомнения.
[Обновление: положение параметра]
Я немного поигрался с этим и, кажется, нашел, когда простой синтаксис (без передачи параметров ref) нарушается.
public static void TryParseArray(string input, out int[] result) {
result = new int[0];
}
public static void TryParseArray_2(out int[] result, string input) {
result = new int[0];
}
let arr = csharp.TryParseArray("a") // OK
let arr = csharp.TryParseArray_2("a") // ERROR
Похоже, что параметр out должен быть в конце (= за ним не следуют обычные параметры) в методах C#, чтобы F# мог использовать их как возвращаемый кортеж.
ref
, но не так, вместо этого определите переменныеa
иb
какref Array.empty<byte>
, а затем передайте их в качестве аргумента (без ключевого слова ref). Вы также можете просто сделать ихmutable
и передать адрес. - person s952163   schedule 14.11.2020