Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I'm a bit late for the party, but i still would like to add some info on writable constans.</p> <p>First of all, as Johan and David stated global and local constants do not differ in memory.</p> <p>For those interested in usage of writable constants: I found it useful to emulate "Promise" functionality to make the function "Lazy". Ofcourse delphi doesn't support Promises, so this is only partially efficient.</p> <p>Consider a function to count amount of words in a string:</p> <pre><code>function CountWords(Input: String):Integer; var Worker: TStringList; begin Worker := TStringList.Create; Worker.DelimitedText := Input; Result := Worker.Count; Worker.Free; end; </code></pre> <p>Now imagine it beeing called many times in our program. TStringList object will be created and freed each time we do it thus doing extra job. You could ofcourse solve this by creating a global variable Worker_CountWords, initialize it on program start and use it in your function, but take a look at this:</p> <pre><code>function CountWords(Input: String):Integer; {$J+} //Enable writable constants const Worker: TStringList = nil; {$J-} //Disable writable constants begin if Worker = nil then begin Worker := TStringList.Create; //Other Initialization code here end; Worker.DelimitedText := Input; Result := Worker.Count; end; </code></pre> <p>This function will only create TStringList once and use it later, but will never free it (kind of a downside here). But for a function that can be called any time during the app is running this is sort of suitable. This can make your code look a bit cleaner if you will... Now, notice - this isn't actually a promise, but it achieves similar results. You could aslo do this with function calls (i've already tried replacing the actual function in memory and it's pretty bad idea, but you could make a const that will hold pointer to function, which at start holds pointer to initialization function and after that replaced to actual worker function and the parent function would only have a call to a function which is held in a constant). I cannot think of a good example right now, so i'll let you figure that one out on your own.</p> <p>Also it is not required to have {$WRITABLECONST ON} in order to modify constant values, you could also do something like this:</p> <pre><code>procedure DoSomeWork; const FirstCall : TDateTime = 0; begin if FirstCall = 0 then PDateTime(@FirstCall)^ := Now; Writeln(TimeToStr(FirstCall)); //some actual work here end; </code></pre> <p>Same thing applies to <code>const</code> parameters in functions, because they are exactly same as <code>var</code> parameters (passed by reference to avoid spending time on creating separate variables), the only difference is that compiler doesn't allow you to change these values normally.</p> <p>P.S. Be careful with const function parameters, since you can pass actual constants like <code>foo(12)</code> and trying to modify that could probably mess something up...</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload