Методы расширения в D?

Привет, ребята, я пытаюсь понять эти фрагменты синтаксиса:

S[] split(S)(S s) if (isSomeString!S)
{
    ...
}

а также

string join(in string[] words, string sep)
{
    ...
}

(Как показано в phobos/src/std/string.d)

Насколько я могу судить, это фрагмент кода, который позволяет нам делать такие вещи, как:

string[] parts = "/foo/bar/baz".split("/"); // string[] {"foo", "bar", "baz"}
string part = parts.join("-"); // string "foo-bar-baz"

Что в основном заставляет меня поверить, что что-то вроде методов расширения, которые я знаю из CSharp, возможны в d. У меня проблемы:

  1. Что я не уверен на 100%, что смотрю здесь правильные объявления функций
  2. Что я не вижу, что делает их похожими.

person Kris    schedule 21.01.2011    source источник
comment
Из документации: digitalmars.com/d/2.0/arrays. html#func-as-property.   -  person Corbin March    schedule 22.01.2011


Ответы (2)


Это не методы расширения как таковые, а просто какая-то ошибка, которая превратилась в изящную функцию.

Сходство между этими двумя методами заключается в том, что оба имеют строку в качестве первого параметра. Итак, трюк, который здесь работает, заключается в том, что задан массив T[] arr и функция

U foo (T[] t, other params)

можно вызвать, выполнив

arr.foo(some arguments matching other params)
person larsivi    schedule 21.01.2011
comment
D2 предполагалось распространить эту ошибку на все типы, но я не знаю, дошел ли Уолтер до этого. - person FeepingCreature; 21.01.2011
comment
Я не уверен, что это действительно была ошибка. Я думаю (но, возможно, ошибаюсь), что это было задумано. OTOH почти все участники считают тот факт, что он работает только для некоторых типов, в лучшем случае неверным. - person BCS; 21.01.2011
comment
Эта функция называется унифицированным синтаксисом вызова функций. И нет, это еще не реализовано для других типов в D2. См. также stackoverflow.com/questions/3868511/non- функции-диапазона-членов/ - person stephan; 21.01.2011

В D любая функция, которая принимает массив в качестве первого аргумента, может вызываться так, как если бы она была функцией-членом этого массива. А поскольку строки — это массивы, они будут включать строки. Итак, что-то вроде

T[] replace(in T[] array, in T[] from, in T[] to)

можно назвать двумя разными способами:

auto replacedStr1 = replace("hello world", "hello", "goodbye");
auto replacedStr2 = "hello world".replace("hello", "goodbye");

Эта функция в настоящее время работает только для массивов (IIRC, это произошло из-за ошибки, которая позволила это сделать, и было решено, что на самом деле было бы неплохо иметь ее, поэтому она фактически стала частью языка), но предположительно, в какой-то момент точки, он будет работать для всех типов. То, что он работает для всех типов, называется единым синтаксисом вызова функций. С этим реализованным вы сможете делать такие вещи, как

auto bigger = 2.max(5);

Но поскольку унифицированный синтаксис вызова функций еще не реализован, вы можете делать такие вещи только с массивами. Люди довольно часто программируют таким образом строки, вместо того, чтобы передавать их в качестве первого аргумента функции.

person Jonathan M Davis    schedule 21.01.2011