2013-01-07 36 views
6

tôi khá mới để Scala và tình cờ vấn đề sau đây:Scala tương đương với C++ biến tĩnh trong một hàm

Scala là những gì tương đương với biến tĩnh chức năng không?

void foo() 
{ 
    static int x = 5; 
    x++; 
    printf("%d", x); 
} 

EDIT:

Những gì tôi muốn đạt được một loại chức năng cuộc gọi truy cập được - Tôi muốn kiểm tra bao nhiêu lần chức năng của tôi đã được thực hiện và trong thời hạn chế khả năng hiển thị của bộ đếm này để không thể sửa đổi nó từ bên ngoài.

+2

Bạn có thể mô tả lý do tại sao bạn tạo 'x' tĩnh? Nó có thể được truy cập từ bên ngoài 'foo' không? Là 'foo' có thể đệ quy? Tôi không phải rất quen thuộc với C++ và biết ý định của bạn sẽ làm cho nó dễ dàng hơn để đưa ra một đoạn mã Scala tương ứng. –

+2

Lập trình chức năng thuần túy tránh loại biến có thể thay đổi này khiến nó dẫn đến một hàm không phải là "trong suốt". – Mik378

+4

C++ side: điều này được gọi là static cục bộ, biến là * global * trong đó chỉ có một cá thể tồn tại trong suốt chương trình, tuy nhiên khả năng hiển thị (phạm vi từ vựng) bị hạn chế đối với phần thân của hàm. Thành ngữ này có thể được sử dụng để triển khai thực đơn, ví dụ. –

Trả lời

18

Đây là một khối mã có hiệu quả tương tự:

scala> object f extends Function0[Unit] { 
    | var x = 0; 
    | def apply = { 
    |  x = x + 1; 
    |  println(x); 
    | } 
    | } 
defined module f 

scala> f() 
1 

scala> f() 
2 

Mặc dù tôi phải nhấn mạnh rằng đây là một thói quen rất xấu vì nó giết chết referential transparency.

Nếu bạn thực sự cần hành vi này xem xét việc này:

type State = Int 

def f(state: State) = { 
val newState = state + 1 
println(state); 
newState; 
} 
+1

Điều này (ví dụ đầu tiên) trên thực tế giống như một hàm C++, nhưng nó thực sự cư xử như thể 'f()' có một biến tĩnh cục bộ. –

+1

Điều này không nhất thiết phải giết tính minh bạch tham chiếu. Việc ghi nhớ xuất hiện trong đầu. – ebruchez

2

Scala không tương đương với các biến tĩnh cục bộ của C++. Trong Scala, các quy tắc phạm vi phù hợp hơn trong C++ hoặc Java - những gì được định nghĩa trong một khối, đi ra khỏi phạm vi khi khối được thoát. Như những người khác đã lưu ý, một biến tĩnh cục bộ sẽ là một hiệu ứng phụ , không mong muốn trong lập trình hàm.

Scala, là ngôn ngữ OO/chức năng lai, có thể viết theo phong cách bắt buộc, nhưng thích và khuyến khích phong cách chức năng (ví dụ: bằng cách tạo các bộ sưu tập bất biến là lựa chọn mặc định). Các biến tĩnh cục bộ, ngoài việc biểu diễn một tác dụng phụ, cũng không có trong Java, đó là một lý do nữa để không cung cấp chúng trong Scala.

1

Để có được tương đương với một C++ biến tĩnh địa phương trong Scala:

import scala.collection.parallel.mutable 
import scala.reflect._ 
import scala.reflect.runtime.universe._ 

object StaticLocal { 
    private val classes = new mutable.ParHashSet[String] 
    private val variables = new mutable.ParHashMap[String, AnyVal] 
} 

import Numeric._ 

class StaticLocal[T <: AnyVal](value:T)(implicit tag: TypeTag[T], num: Numeric[T]){ 
    val name = this.getClass + "." + tag.toString() ; 
    private var inited = false 
    if (!inited) { 
    inited = true 

    if (!StaticLocal.classes.contains(name)) { 
     StaticLocal.classes += name 
     StaticLocal.variables += name -> value.asInstanceOf[AnyVal] 
    } 
    } 
    def get():T = {StaticLocal.variables.get(name) match { case x:Some[Int] => (x.get).asInstanceOf[T] ; case None => throw new Exception("Not found:" + name) }} 
    def set(value:AnyVal) { StaticLocal.variables.put(name, value)} 
    def +(v:StaticLocal[T]):T = { num.plus(this.get, v.get) } 
    def +(v:T):T = { num.plus(this.get, v) } 
    def +=(v:T):Unit = { set(num.plus(this.get, v)) } 
    def +=(v:StaticLocal[T]):Unit = { set(num.plus(this.get, v.get)) } 

    override def toString() = { get.toString} 
    implicit def StaticLocalWrapper(s: StaticLocal[T]):T = s.get 
} 

Sau đó, trong phương pháp:

def foo():Unit 
{ 
    object x extends StaticLocal(5) 
    x += 1 
    println(x) 
}   

Điều này sẽ hoạt động giống như trong C++, bao gồm khi phương thức hoặc việc sở hữu cá thể lớp vượt quá phạm vi (mặc dù vậy là w ith một hình phạt hiệu suất). Không an toàn chỉ vì nó đứng.

Các vấn đề liên quan