kzen.dev
  • Întrebări
  • Tag-uri
  • Utilizatori
Notificări
Recompense
Înregistrare
După înregistrare, veți primi notificări despre răspunsurile și comentariile la întrebările DVS.
Logare
Dacă aveţi deja un cont, autentificaţi-vă pentru a verifica notificările noi.
Aici vor fi recompensele pentru întrebările, răspunsurile și comentariile adăugate sau modificate.
Mai mult
Sursă
Editează
Amir Karimi
Amir Karimi
Question

Care este diferența dintre "def" și "val" pentru a defini o funcție

Care este diferența între:

def even: Int => Boolean = _ % 2 == 0

și

val even: Int => Boolean = _ % 2 == 0

Ambele pot fi numite ca chiar(10).

205 2013-09-19T06:08:42+00:00 8
Amir Karimi
Amir Karimi
Întrebarea editată 29 ianuarie 2014 в 9:24
Programare
scala
Solution / Answer
 senia
senia
19 septembrie 2013 в 6:15
2013-09-19T06:15:17+00:00
Mai mult
Sursă
Editează
#22264975

Metoda def chiar evaluează pe apel și creează o nouă funcție de fiecare data (nou exemplu deFunction1`).

def even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = false

val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true

Cu def puteți obține noua funcție pe fiecare apel:

val test: () => Int = {
  val r = util.Random.nextInt
  () => r
}

test()
// Int = -1049057402
test()
// Int = -1049057402 - same result

def test: () => Int = {
  val r = util.Random.nextInt
  () => r
}

test()
// Int = -240885810
test()
// Int = -1002157461 - new result

"val" evaluează, atunci când sunt definite, def - atunci când este solicitat:

scala> val even: Int => Boolean = ???
scala.NotImplementedError: an implementation is missing

scala> def even: Int => Boolean = ???
even: Int => Boolean

scala> even
scala.NotImplementedError: an implementation is missing

Rețineți că există o a treia opțiune: leneș val.

Acesta evaluează, atunci când a sunat prima dată:

scala> lazy val even: Int => Boolean = ???
even: Int => Boolean = <lazy>

scala> even
scala.NotImplementedError: an implementation is missing

Dar returnează același rezultat (în acest caz, aceeași instanță a FunctionN), de fiecare dată:

lazy val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true

lazy val test: () => Int = {
  val r = util.Random.nextInt
  () => r
}

test()
// Int = -1068569869
test()
// Int = -1068569869 - same result

Performanță

"val" evaluează, atunci când sunt definite.

def evaluează la fiecare apel, astfel de performanță ar putea fi mai rău decât " val " pentru mai multe apeluri. Te'll obține aceeași performanță cu un singur apel. Și nu te cheamă'll nr aeriene din def, astfel încât să puteți defini chiar dacă nu-l va folosi în unele ramuri.

Cu un leneș de valte&#39;ll obține un leneș de evaluare: puteți defini chiar dacă nu-l va folosi în unele ramuri, și se evaluează o dată sau nu, dar&#39;ll a obține un pic de regie de verificare dublu de blocare pe fiecare acces laleneș val`.

Ca @SargeBorsch remarcat-ai putea defini metoda, și aceasta este cea mai rapidă opțiune:

def even(i: Int): Boolean = i % 2 == 0

Dar dacă ai nevoie de o funcție (nu metoda) pentru funcția de compoziție sau pentru funcții de ordin superior (cum ar fi filtru(chiar)) compilatorul va genera o funcție de metoda ta de fiecare dată când îl utilizați-l ca funcție, astfel de performanță ar putea fi ușor mai rău decât cu "val".

Ismail Marmoush
Ismail Marmoush
Răspuns editat 25 iulie 2017 в 10:23
316
0
 Jatin
Jatin
19 septembrie 2013 в 6:15
2013-09-19T06:15:15+00:00
Mai mult
Sursă
Editează
#22264974

Luați în considerare acest lucru:

scala> def even: (Int => Boolean) = {
             println("def"); 
             (x => x % 2 == 0)
       }
even: Int => Boolean

scala> val even2: (Int => Boolean) = {
             println("val");
             (x => x % 2 == 0)
       }
val //gets printed while declaration. line-4
even2: Int => Boolean = <function1>

scala> even(1)
def
res9: Boolean = false

scala> even2(1)
res10: Boolean = false

Vezi diferența? Pe scurt:

def: Pentru fiecare apel de a "chiar", se solicită corpul "chiar" metoda din nou. Dar cu even2 adică val, funcția este inițializat doar o singură dată în timp ce declarația (și, prin urmare, se imprimă " val " de la linia 4 și niciodată din nou) și aceeași ieșire este utilizată de fiecare dată când este accesat. De exemplu, incearca sa faci acest lucru:

scala> import scala.util.Random
import scala.util.Random

scala> val x = { Random.nextInt }
x: Int = -1307706866

scala> x
res0: Int = -1307706866

scala> x
res1: Int = -1307706866

Atunci când " x " este inițializat, valoarea returnată de Aleatorie.nextInt` este setată ca valoare finală de "x". Data viitoare când " x " este folosit din nou, se va întoarce întotdeauna aceeași valoare.

Puteți, de asemenea, alene inițializa "x". adică prima dată când este utilizat, este inițializat și nu în timp ce declarația. De exemplu:

scala> lazy val y = { Random.nextInt }
y: Int = <lazy>

scala> y
res4: Int = 323930673

scala> y
res5: Int = 323930673
 Jatin
Jatin
Răspuns editat 13 februarie 2014 в 8:48
23
0
Apurva Singh
Apurva Singh
7 iunie 2017 в 8:26
2017-06-07T20:26:15+00:00
Mai mult
Sursă
Editează
#22264976

Vezi asta:

  var x = 2 // using var as I need to change it to 3 later
  val sq = x*x // evaluates right now
  x = 3 // no effect! sq is already evaluated
  println(sq)

În mod surprinzător, acest lucru se va imprima 4 și nu 9! val (chiar var) este evaluat imediat și alocate.
Schimba acum pe val la def.. se va imprima 9! Def este un apel de funcție.. se va evalua de fiecare dată când este chemat.

5
0
 Sandi
Sandi
14 ianuarie 2018 в 4:21
2018-01-14T04:21:55+00:00
Mai mult
Sursă
Editează
#22264978

val de exemplu "mp" este de Scala definiție este fix. Este evaluată corect la momentul declarației, puteți't schimba mai târziu. În alte exemple, în cazul în care even2, de asemenea, val, dar a declarat cu funcția semnătura și anume "(Int => Boolean)", așa că nu este de tip Int. Este o funcție și l's valoare este stabilită de următoarea expresie

   {
         println("val");
         (x => x % 2 == 0)
   }

Ca pe Scala val de proprietate, puteți't atribui o altă funcție a even2, aceeași regulă ca sq.

Despre ce asteptare eval2 val funcția de imprimare nu "val" din nou și din nou ?

Orig cod:

val even2: (Int => Boolean) = {
             println("val");
             (x => x % 2 == 0)
       }

Știm, în Scala ultima declarație de mai sus un fel de exprimare (în interiorul { .. }) este, de fapt, a reveni la partea stângă. Deci ajungi stabilirea even2 la "x => x % 2 == 0" funcție, care se potrivește cu tipul declarat pentru even2 val de tip anume (Int => Boolean), deci compiler este fericit. Acum even2 doar puncte de la "(x => x % 2 == 0)" funcție (nu orice altă declarație înainte și anume println("val"), etc. Invocarea event2 cu parametri diferiți de fapt va invoca "(x => x % 2 == 0)" codul, ca doar asta este salvat cu event2.

scala> even2(2)
res7: Boolean = true

scala> even2(3)
res8: Boolean = false

Doar pentru a clarifica acest lucru mai mult, în urma este o altă versiune a codului.

scala> val even2: (Int => Boolean) = {
     |              println("val");
     |              (x => { 
     |               println("inside final fn")
     |               x % 2 == 0
     |             })
     |        }

Ce se va întâmpla ? aici vom vedea "în interiorul final fn" tipărită din nou și din nou, atunci când apelați even2().

scala> even2(3)
inside final fn
res9: Boolean = false

scala> even2(2)
inside final fn
res10: Boolean = true

scala> 
1
0
Gaurav Khare
Gaurav Khare
26 ianuarie 2018 в 1:08
2018-01-26T13:08:39+00:00
Mai mult
Sursă
Editează
#22264979

Executare o definiție cum ar fi def x = e nu va evalua expresia e. În locul e este evaluată ori de câte ori x este invocată.

Alternativ, Scala oferă o valoare definiție val x = e,care face evaluarea dreapta-side, ca parte a evaluării de definiție. Dacă x este apoi utilizat ulterior, este imediat înlocuit de pre-calculat valoarea lui e, astfel că expresia nu trebuie să fie evaluate din nou.

1
0
 GraceMeng
GraceMeng
11 ianuarie 2019 в 11:36
2019-01-11T23:36:34+00:00
Mai mult
Sursă
Editează
#22264981

În REPL,

scala> def even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean

scala> val even: Int => Boolean = { _% 2 == 0 }
even: Int => Boolean = $$Lambda$1157/[email protected]

def înseamnă apel-cu-numele, evaluate la cerere

val înseamnă call-by-value, evaluate în timp ce inițializarea

0
0
 prateek
prateek
11 iulie 2018 в 8:15
2018-07-11T08:15:13+00:00
Mai mult
Sursă
Editează
#22264980

În plus față de cele de mai sus răspunsuri utile, concluziile mele sunt:

def test1: Int => Int = {
x => x
}
--test1: test1[] => Int => Int

def test2(): Int => Int = {
x => x+1
}
--test2: test2[]() => Int => Int

def test3(): Int = 4
--test3: test3[]() => Int

De mai sus arată că "def" este o metodă (cu zero argument parametrii) care returnează o altă funcție "Int => Int" atunci când este invocată.

Conversia metodelor de funcții este bine explicat aici: https://tpolecat.github.io/2014/06/09/methods-functions.html

 jkdev
jkdev
Răspuns editat 11 iulie 2018 в 8:41
0
0
Sandipan Ghosh
Sandipan Ghosh
20 septembrie 2017 в 9:18
2017-09-20T09:18:57+00:00
Mai mult
Sursă
Editează
#22264977

de asemenea, Val este de valoarea de evaluare. Ceea ce înseamnă partea dreaptă expresie este evaluată în timpul definiție. În cazul în care Def este de nume de evaluare. Acesta nu va evalua până it's a folosit.

0
0
Adăugati o întrebare
Categorii
Toate
Tehnologii
Cultură
Viață / Artă
Stiință
Profesii
Afaceri
Utilizatori
Toate
Nou
Populare
1
Daniel Gogov
Înregistrat 6 zile în urmă
2
工藤 芳則
Înregistrat 1 săptămână în urmă
3
Ирина Беляева
Înregistrat 2 săptămâni în urmă
4
Darya Arsenyeva
Înregistrat 2 săptămâni în urmă
5
anyta nuam-nuam (LapuSiK)
Înregistrat 2 săptămâni în urmă
ID
JA
KO
RO
RU
© kzen.dev 2023
Sursă
stackoverflow.com
în cadrul licenței cc by-sa 3.0 cu atribuire