Чистый метод должен быть статичным?
В настоящий момент я работаю над учебником, который определяет чистый метод:
" статический метод, который зависит только от его параметров и других данных"
Было бы невозможно, чтобы метод экземпляра был чистым методом, не будучи статическим (если он не изменяет параметры и не имеет "побочных эффектов", например, печать)?
Я знаю, что чистый метод должен быть чистым, возвращаемое значение зависит только от параметров, а не от какого-либо другого состояния, поэтому, возможно, метод методов экземпляра означает, что переменные, взятые из объекта, вызывающего метод, не считаются параметры, но как другое "состояние"?
Помимо этого, я не могу думать о какой-либо причине, почему нестатический метод не может быть чистым методом.
Вот пример:
public class Rational {
private int numer;
private int denom;
public Rational() {
this.numer = 0;
this.denom = 1;
}
public Rational(int numer, int denom) {
this.numer = numer;
this.denom = denom;
}
}
Вышеупомянутый определяет класс Rational
Затем вы могли бы написать метод в классе Rational
который возвращает объект Rational
как double
либо "Метод один", либо "Метод два" ниже.
Первый метод:
public double toDouble() {
double x = this.numer;
double y = this.denom;
double fprat = x / y;
return fprat;
}
Второй способ:
public static double toDouble(Rational rational)
{
double x = rational.numer;
double y = rational.denom;
double fprat = x / y;
return fprat;
}
Они по сути делают одно и то же, но одно - статический метод, а другой - метод экземпляра, поэтому их вызовы будут в другом формате. Метод второй, безусловно, является чистым методом, но не будет ли метод один, который не является статичным, также как чистый метод в этих условиях?
Ответы
Ответ 1
"Статическая" часть этого определения является излишней. Статический метод не гарантирует, что он не полагается на какое-либо другое состояние. Я подозреваю, что определение просто хотело удостовериться, что метод не использует переменные экземпляра.
С другой стороны, технически вы также можете думать о методе экземпляра как статическом методе с нулевым параметром, самим объектом. Если этот объект является immmutable (или метод ничего не меняет в объекте), вы можете утверждать, что метод по-прежнему чист. В основном вы рассматриваете "объект" как дополнительный параметр.
Например, ссылки на методы в Java могут вести себя таким образом, делая первый аргумент самим объектом, на который вызывается метод.
Ответ 2
Чистый метод также может быть статичным. Согласно критерию Википедии, два критерия для чистого метода:
-
Функция всегда оценивает одно и то же значение результата с учетом того же значения (-ов) аргументов. Значение результата функции не может зависеть от какой-либо скрытой информации или состояния, которое может измениться во время выполнения программы или между различными исполнениями программы, а также не может зависеть от любого внешнего входа от устройств ввода/вывода.
-
Оценка результата не вызывает каких-либо семантически наблюдаемых побочных эффектов или результатов, таких как мутация изменяемых объектов или выход на устройства ввода/вывода.
(акцент мой)
Нет причин, по которым это не может применяться к нестационарному методу. Создание статического метода приведет к тому, что вызывающий объект будет более уверенным, что состояние экземпляра не используется, поэтому, вероятно, лучше сделать его статическим.
В зависимости от вашей точки зрения, метод экземпляра можно рассматривать как просто функцию, принимающую дополнительный неявный аргумент: сам экземпляр. Таким образом, нестатический метод может опираться на состояние экземпляра и считаться чистым при условии, что он не полагается на какое-либо внешнее состояние (одноточие и т.д.) Или создает побочные эффекты. Роберт ответ положил это красиво. Это зависит от интерпретации, но мое мнение состоит в том, что такой метод будет чистым.
Voo вложил это в комментарии:
Почему скрытый этот указатель считается более особенным, чем любой другой параметр функции? Этот аргумент приводит к противоречию. Предположим, что
public static int pureFunc(MyInstance self)
чисто, ясно изоморф
public int pureFunc()
будет чистым.
Ответ 3
Концептуально единственная разница между статическим методом и методом экземпляра заключается в том, что метод экземпляра имеет скрытый параметр, доступный через this
ключевое слово.
Поэтому метод экземпляра, который не мутирует this
является чистым, если он иначе квалифицируется как чистый статический метод.
Проблема здесь может быть связана с виртуальной отправкой, которая предотвращается static
. Метод базового класса может быть чистым, в то время как метод производного класса может быть нечистым, в то время как их контракт в системе типа Java равен.
Ответ 4
"Чистое" в основном означает "зависит только от его аргументов и не имеет побочных эффектов".
Статический метод не должен быть чистым, поскольку он может обращаться к статической структуре данных. Точно так же метод экземпляра может быть чистым, поскольку он не имеет доступа к каким-либо переменным экземпляра.
Таким образом, понятия "статический" и "экземпляр" напрямую не связаны с понятием "чистый".
Ответ 5
Этот метод:
public int add(int a, int b) {
return a + b;
}
не является статическим, но его возвращаемое значение не зависит ни от чего, кроме параметров. Но из-за этого add
не обязательно должен быть методом экземпляра вообще!
Я думаю, что это то, к чему идет ваш учебник - методы экземпляров, которые не имеют доступа к состоянию или мутируют состояние, также могут быть статическими.
Предполагается, что методы экземпляров зависят от состояния объекта, иначе он должен быть статическим методом. И статические методы, которые не зависят от статических состояний, являются чистыми.
Ответ 6
Нет никакой гарантии, что static
метод pure
. Технически статический метод может иметь статическое состояние. Вот почему ваше предположение
"статический метод, который зависит только от его параметров и других данных"
неправда.
EDIT после комментария Берги
Как я уже говорил, static
ключевое слово не гарантирует отсутствие состояния. Если вы опустите static
ключевое слово в своей цитате, оно все равно будет истинным.
Поэтому отвечая на ваш вопрос. Чистый метод должен быть статичным? Ответ в этом зависит.
Есть преимущества от создания чистой функции статической, то есть:
-
Это самопроверка, которая гарантирует, что вы не (случайно) меняете состояние в своем классе;
-
Этот метод нельзя переопределить. Это гарантирует, что метод не изменит состояние в будущем.
Но, с другой стороны, трудно издеваться над статическими методами, и это может быть проблемой во время тестирования.