programacion procedimientos procedimiento método metodos metodo función funciones funcion explicar entre ejemplos diferencia function scala methods

function - procedimientos - funciones y metodos en programacion



Diferencia entre método y función en Scala. (6)

función Se puede invocar una función con una lista de argumentos para producir un resultado. Una función tiene una lista de parámetros, un cuerpo y un tipo de resultado. Las funciones que son miembros de un objeto clase, rasgo o singleton se denominan métodos . Las funciones definidas dentro de otras funciones se llaman funciones locales. Las funciones con el tipo de resultado de la Unidad se denominan procedimientos. Las funciones anónimas en el código fuente se llaman funciones literales. En el tiempo de ejecución, los literales de función se instancian en objetos llamados valores de función.

Programación en Scala Segunda Edición. Martin Odersky - Cuchara Lex - Bill Venners

Leí las funciones de Scala (parte de Otra gira de Scala ). En ese post declaró:

Métodos y funciones no son lo mismo.

Pero él no explicó nada al respecto. ¿Qué estaba tratando de decir?


Aquí hay un buen artículo del cual se toman la mayoría de mis descripciones. Solo una breve comparación de funciones y métodos con respecto a mi comprensión. Espero eso ayude:

Funciones : Son básicamente un objeto. Más precisamente, las funciones son objetos con un método de aplicación; Por lo tanto, son un poco más lentos que los métodos debido a su sobrecarga. Es similar a los métodos estáticos en el sentido de que son independientes de un objeto a invocar. Un ejemplo simple de una función es como a continuación:

val f1 = (x: Int) => x + x f1(2) // 4

La línea anterior no es nada, excepto asignar un objeto a otro como object1 = object2. En realidad, el objeto2 en nuestro ejemplo es una función anónima y el lado izquierdo obtiene el tipo de un objeto debido a eso. Por lo tanto, ahora f1 es un objeto (Función). La función anónima es en realidad una instancia de Function1 [Int, Int] que significa una función con 1 parámetro de tipo Int y valor de retorno de tipo Int. Llamar a f1 sin los argumentos nos dará la firma de la función anónima (Int => Int =)

Métodos : no son objetos sino que están asignados a una instancia de una clase, es decir, un objeto. Exactamente lo mismo que el método en java o las funciones miembro en c ++ (como lo señaló Raffi Khatchadourian en un comentario a esta pregunta ) y etc. Un ejemplo simple de un método es como el siguiente:

def m1(x: Int) = x + x m1(2) // 4

La línea anterior no es una simple asignación de valor sino una definición de un método. Cuando invocas este método con el valor 2 como la segunda línea, la x se sustituye por 2 y el resultado se calculará y obtendrás 4 como salida. Aquí obtendrá un error si simplemente escribe m1 porque es un método y necesita el valor de entrada. Al usar _ puedes asignar un método a una función como la siguiente:

val f2 = m1 _ // Int => Int = <function1>


Digamos que tienes una lista

scala> val x =List.range(10,20) x: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19)

Define un método

scala> def m1(i:Int)=i+2 m1: (i: Int)Int

Definir una función

scala> (i:Int)=>i+2 res0: Int => Int = <function1> scala> x.map((x)=>x+2) res2: List[Int] = List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)

Método que acepta el argumento

scala> m1(2) res3: Int = 4

Definiendo la función con val

scala> val p =(i:Int)=>i+2 p: Int => Int = <function1>

Argumento para funcionar es opcional

scala> p(2) res4: Int = 4 scala> p res5: Int => Int = <function1>

Argumento al método es obligatorio

scala> m1 <console>:9: error: missing arguments for method m1; follow this method with `_'' if you want to treat it as a partially applied function

Consulte el siguiente Tutorial que explica cómo pasar otras diferencias con ejemplos como otro ejemplo de diff con la función Método Vs, Uso de la función como Variables, función de creación que devolvió la función


Jim tiene esto bastante cubierto en jim-mcbeath.blogspot.com/2009/05/… , pero estoy publicando una sesión informativa aquí como referencia.

Primero, veamos que nos dice la Especificación Scala. El Capítulo 3 (tipos) nos informa sobre los Tipos de función (3.2.9) y los Tipos de método (3.3.1). El Capítulo 4 (declaraciones básicas) habla de Declaración de Valores y Definiciones (4.1), Declaración de Variables y Definiciones (4.2) y Declaración de Funciones y Definiciones (4.6). El capítulo 6 (expresiones) habla de funciones anónimas (6.23) y valores de métodos (6.7). Curiosamente, los valores de función se mencionan una vez en 3.2.9, y en ninguna otra parte.

Un tipo de función es (aproximadamente) un tipo de formulario (T1, ..., Tn) => U , que es una abreviatura de la FunctionN en la biblioteca estándar. Las funciones anónimas y los valores de los métodos tienen tipos de funciones, y los tipos de funciones se pueden usar como parte de las declaraciones y definiciones de funciones, variables y funciones. De hecho, puede ser parte de un tipo de método.

Un tipo de método es un tipo sin valor . Eso significa que no hay valor, ni objeto, ni instancia, con un tipo de método. Como se mencionó anteriormente, un valor de método en realidad tiene un tipo de función . Un tipo de método es una declaración de def : todo sobre una def excepto su cuerpo.

Las Declaraciones y Definiciones de Valores y las Declaraciones y Variables de Variables son declaraciones val y var , que incluyen tanto el tipo como el valor , que pueden ser, respectivamente, Tipo de función y Funciones anónimas o Valores de método . Tenga en cuenta que, en la JVM, estos (valores de método) se implementan con lo que Java denomina "métodos".

Una declaración de función es una declaración de def , que incluye tipo y cuerpo . La parte de tipo es el Tipo de método y el cuerpo es una expresión o un bloque . Esto también se implementa en la JVM con lo que Java llama "métodos".

Finalmente, una función anónima es una instancia de un tipo de función (es decir, una instancia del rasgo FunctionN ), y un valor de método es lo mismo. La distinción es que el valor de un método se crea a partir de métodos, ya sea mediante la fijación posterior de un guión bajo ( m _ es un valor del método correspondiente a la "declaración de función" ( def ) m ), o mediante un proceso llamado expansión eta , que es como Reparto automático del método al funcionamiento.

Eso es lo que dicen las especificaciones, así que permítanme poner esto por adelantado: ¡no usamos esa terminología! Conduce a demasiada confusión entre la llamada "declaración de función" , que forma parte del programa (capítulo 4 - declaraciones básicas) y la "función anónima" , que es una expresión, y el "tipo de función" , que es, Bueno, un tipo - un rasgo.

La terminología a continuación, y utilizada por programadores experimentados de Scala, hace un cambio a partir de la terminología de la especificación: en lugar de decir declaración de función , decimos método . O incluso declaración de método. Además, observamos que las declaraciones de valores y las declaraciones de variables también son métodos para fines prácticos.

Entonces, dado el cambio anterior en la terminología, aquí hay una explicación práctica de la distinción.

Una función es un objeto que incluye uno de los rasgos de FunctionX , como Function0 , Function1 , Function2 , etc. También podría incluir PartialFunction , que en realidad amplía Function1 .

Veamos la firma de tipo para uno de estos rasgos:

trait Function2[-T1, -T2, +R] extends AnyRef

Este rasgo tiene un método abstracto (también tiene algunos métodos concretos):

def apply(v1: T1, v2: T2): R

Y eso nos dice todo lo que hay que saber al respecto. Una función tiene un método de apply que recibe N parámetros de los tipos T1 , T2 , ..., TN y devuelve algo de tipo R Es contra-variante en los parámetros que recibe, y co-variante en el resultado.

Esa variación significa que una Function1[Seq[T], String] es un subtipo de Function1[List[T], AnyRef] . Ser un subtipo significa que se puede usar en lugar de él. Uno puede ver fácilmente que si voy a llamar a f(List(1, 2, 3)) y espera un AnyRef vuelta, cualquiera de los dos tipos anteriores funcionaría.

Ahora, ¿cuál es la similitud de un método y una función? Bueno, si f es una función y m es un método local para el alcance, entonces ambos pueden llamarse así:

val o1 = f(List(1, 2, 3)) val o2 = m(List(1, 2, 3))

Estas llamadas son en realidad diferentes, porque la primera es solo un azúcar sintáctico. Scala lo expande a:

val o1 = f.apply(List(1, 2, 3))

Que, por supuesto, es un método llamado al objeto f . Las funciones también tienen otros azúcares sintácticos en su beneficio: funciones literales (dos de ellas, en realidad) y (T1, T2) => R firmas de tipo. Por ejemplo:

val f = (l: List[Int]) => l mkString "" val g: (AnyVal) => String = { case i: Int => "Int" case d: Double => "Double" case o => "Other" }

Otra similitud entre un método y una función es que el primero se puede convertir fácilmente en el segundo:

val f = m _

Scala lo expandirá, asumiendo que el tipo m es (List[Int])AnyRef en (Scala 2.7):

val f = new AnyRef with Function1[List[Int], AnyRef] { def apply(x$1: List[Int]) = this.m(x$1) }

En Scala 2.8, en realidad usa una clase AbstractFunction1 para reducir el tamaño de las clases.

Observe que no se puede convertir al revés, de una función a un método.

Los métodos, sin embargo, tienen una gran ventaja (bueno, dos: pueden ser un poco más rápidos): pueden recibir parámetros de tipo . Por ejemplo, mientras que f arriba puede necesariamente especificar el tipo de List que recibe ( List[Int] en el ejemplo), m puede parametrizarlo:

def m[T](l: List[T]): String = l mkString ""

Creo que esto cubre prácticamente todo, pero estaré encantado de complementar esto con las respuestas a cualquier pregunta que pueda quedar.


Las funciones no son compatibles con los parámetros predeterminados. Los métodos hacen. La conversión de un método a una función pierde los parámetros predeterminados. (Scala 2.8.1)


Una gran diferencia práctica entre un método y una función es lo que significa el return . return solo devoluciones de un método. Por ejemplo:

scala> val f = () => { return "test" } <console>:4: error: return outside method definition val f = () => { return "test" } ^

El retorno de una función definida en un método hace un retorno no local:

scala> def f: String = { | val g = () => { return "test" } | g() | "not this" | } f: String scala> f res4: String = test

Mientras que regresar de un método local solo regresa de ese método.

scala> def f2: String = { | def g(): String = { return "test" } | g() | "is this" | } f2: String scala> f2 res5: String = is this