В чем разница между "to" и "as" такими префиксами имен методов, как
- составлять список(),
- asList (),
- и т.д...
Когда использовать что при разработке метода?
Ожидается, что toXYZ()
функция будет выполнять преобразование и возвращать новый независимый объект (хотя неизменность позволяет оптимизировать, java.lang.String.toString()
просто возвращает объект).
В качестве примера, в C ++ мы std::bitset::to_ulong()
можем легко потерпеть неудачу, и целый ряд to_string()
всех (более или менее) выполняет сложное преобразование и выделение памяти.
С asXYZ()
другой стороны, ожидается, что функция будет возвращать (потенциально другое) представление об источнике, выполняя минимальную работу.
В качестве примера, в C ++ мы имеем, std::as_const()
который просто возвращает постоянную ссылку, и более сложный, std::forward_as_tuple
который также ссылается на свои аргументы по ссылке.
std::to_string(x)
создает новый строковый объект, ноstd::as_const(x)
создает ссылку (представление) на существующий объект.Честно говоря, это может быть просто несоответствие имен. Если посмотреть на стандартных библиотечных объектов в Smalltalk, например, все методы , которые делают «сложные преобразования» или «возвращать простые представления в другом типе» начинаются с
as
, какasString
,asFloat
,asSeconds
и стандартный метод для преобразования ничего к чему -то еще,as: aClass
.В Ruby, одни и те же виды методов с префиксом
to_
, как и вto_s
,to_a
,to_h
, сокращениеstring
,array
иhash
соответственно.Кажется, что ни одна из стандартных библиотек не проводит различий между различными видами преобразований, вероятно, потому, что это следует рассматривать как деталь реализации.
Однако в Java мы видим много путаницы. Как уже упоминалось, есть
toString
,asList
и так далее. Я считаю, что это просто несоответствие именования, потому что, если вы попытаетесь определить разные значения для каждого префикса, вы всегда найдете контрпример в другом месте стандартной библиотеки.Так что в любом случае я бы сказал, что для вас и вашей команды важно выбрать один префикс и использовать его последовательно во всем коде. Последовательность является ключом, поэтому людям не остается удивляться, как и вам.
источник
toString
создает новую строку, полностью отключенную от объекта (и нет другого пути из-за неизменности). То же самое верно, например, дляCollection#toArray
, покаArrays#asList
возвращает представление массива, который связан двунаправленно (изменение массива изменяет список и наоборот). Так что это довольно непротиворечиво, хотя могут быть и исключения. Выбор одного префикса был бы неправильным. Если бы былоArrays#toList
, то я бы ожидал, что это создаст новый список с новым базовым массивом.Хотя уже есть принятый ответ, похоже, что он сосредоточен на C ++, а вопрос помечен java . В Java первым примером, который приходит на ум для такого рода вещей, является Arrays.asList , который возвращает, по сути, представление массива, заключенного в список. Базовый массив и список все еще связаны; изменения в массиве отражаются в списке и наоборот. Однако массив, возвращаемый методом toArray списка, не зависит от исходного массива и списка:
Все это говорит о том, что нет гарантии, что каждый разработчик библиотеки будет следовать этому соглашению, поэтому вам все равно нужно проверить документацию, чтобы выяснить, будет ли это поведение, которое вы получите от неизвестного кода.
Другое место, которое я видел как методы ... (), часто используемые в преобразовании типов в подтипы. Например, если у вас есть перечислимый набор подтипов, то вы можете получить такой код:
источник
Разница, которую я заметил (только сейчас, подумав об этом)
Итак, мы видим AsInteger и AsString и видим ToArray и ToStringList.
Это подразумевает преобразование, которое имеет смысл (это движение, процесс). Как подразумевается представление, способ выражения исходного объекта.
Еще один способ взглянуть на это:
И затем есть "предшествующий уровень техники" (или наследство), чтобы иметь дело с. До того, как языки были полностью OO с нуля, у вас были бы библиотечные функции, такие как StrToInt () и IntToStr (). Они выполняли преобразования, они были операциями, поэтому имело смысл называть их SomethingToSomethingelse (). В конце концов, To более активен, чем As. Я особенно думаю о Delphi здесь.
Когда C # был спроектирован с амбициями полностью перейти на OO, имело смысл иметь метод для целочисленного объекта, который преобразует целое число в строку. Хотя у нас также есть класс Convert, преобразование в строку настолько распространено, что он стал виртуальным методом для объекта. Дизайнеры, возможно, решили, что ToString будет более знакомым людям из старой парадигмы, и, возможно, именно поэтому мы получили виртуальный метод ToString (), а не виртуальное свойство AsString.
источник
toString()
?