2011-01-21 5 views
2

Эй, ребята, я пытаюсь получить эти биты синтаксиса, чтобы сделать для меня смысл:Методы расширения в 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. То, что я не вижу, что делает их похожими.
+2

Из документов: http://www.digitalmars.com/d/2.0/arrays.html#func-as-property. –

ответ

7

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

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

U foo (T[] t, other params) 

можно назвать, делая

arr.foo(some arguments matching other params) 
+1

D2 был _supposed_, чтобы обобщить эту ошибку на все типы, но я не знаю, когда Уолтер когда-либо обходил ее. – FeepingCreature

+1

Я не уверен, что это действительно ошибка. Я думаю (но, возможно, не помню), что это было по дизайну. OTOH почти каждый вовлеченный считает, что он работает только для некоторых типов, которые в лучшем случае являются неправильными. – BCS

+3

Функция называется «Унифицированный синтаксис вызова функции». И нет, он еще не реализован для других типов в D2. См. Также http://stackoverflow.com/questions/3868511/non-member-range-functions/3868943#3868943 – stephan

3

В 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); 

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