millionchart
English

نوع‌ها در حالت سایه

زبان چه نوع‌هایی دارد، نوع را کجا می‌نویسید، بررسی نوع در edition 1 چه چیزی را گزارش می‌کند و چه چیزی را فقط می‌شمارد. نوع هرگز رفتار اسکریپت را عوض نمی‌کند.

edition 1 نوع دارد، اما آن را اجبار نمی‌کند. می‌توانید بعد از یک نام نوعش را بنویسید و رکوردها و enumهای خودتان را تعریف کنید، و بررسی‌کننده آن‌ها را می‌خواند، اما نوع اشتباه در این edition خطا نیست. بررسی نوع در حالت سایه (shadow mode) اجرا می‌شود: مجموعهٔ کوچکی از اشتباه‌ها را گزارش می‌کند (پایین‌تر)، و برای بقیه فقط آنچه را می‌گفت می‌شمارد، برای کسانی که زبان را می‌سازند. اسکریپت با نوع‌هایی که اعلام می‌کند و بدون آن‌ها یکسان اجرا می‌شود.

این صفحه می‌گوید چه چیزی بررسی می‌شود، چه چیزی نمی‌شود، و نوع امروز چه کاری برایتان می‌کند.

نوع‌ها#

گونهنام‌ها
عدد و متنint، float، bool، text، time، price
تنظیمات و منبع‌هاcolor، source، timeframe، symbol، session
مجموعه‌هاarray<T>، map<K, V>، matrix<T>، که با نوع عضوهایشان نوشته می‌شوند: array<float>، map<int, text>
شیءهای نمودارline، label، box، table، polyline و chart.point
مال خودتانیک type (رکوردی با فیلدهای نام‌دار) و یک enum (مجموعهٔ ثابتی از نام‌ها)
مجموعه‌های گزینهمجموعهٔ واژه‌هایی که یک گزینه می‌گیرد، مثل h_align (left، center، right)

نوع را کجا می‌نویسید#

بعد از نام، با دونقطه:

Text
let average: float = tech.sma(close, 20)
mut largest: float = na
state window: array<float> = array<float>()
input length: int = 20, name = "Length"
fn spread(high_price: float, low_price: float): float = high_price - low_price

در یک تابع، نوع پارامترها و نوع نتیجه. در یک type، نوع هر فیلد. نوع یک ورودی بخشی از تعریف آن است (ورودی‌ها).

رکورد با type تعریف می‌شود و با فیلدهایش به نام ساخته می‌شود. متد تابعی است که به شکل fn Type.name(...) نوشته می‌شود: اولین پارامترش مقداری است که جلوی نقطه آمده و معمولاً self نامیده می‌شود. enum با enum تعریف می‌شود و به شکل Name.member خوانده می‌شود:

Cuprel
// Types in shadow mode: a record and an enum are declared, constructed and read, and the checker reports their misuse as findings while the run is unchanged.
indicator "Records and enums"
    edition = 1
    display = pane

enum Trend
    up
    down
    flat

type Reading
    average: float = 0
    trend: Trend = Trend.flat

input length: int = 20, name = "Length", min = 2
let average = tech.sma(close, length)
let reading = Reading(average = average, trend = if close > average then Trend.up else Trend.down)
plot(reading.average, name = "Average")
plot(if reading.trend == Trend.up then 1 else -1, name = "Direction", style = histogram)

رکوردی که در یک state نگه داشته شده، می‌تواند با یک رکورد تازه جایگزین شود و با متدهایش تغییر کند:

Cuprel
// A record kept in a state, with a method of its own. Zone holds a price band and the number of bars that closed inside it.
// A new band is made every `length` bars from the highest high and lowest low; `zone.touch(close)` is a call of the method defined on the type.
indicator "Zone with a record"
    edition = 1
    display = price

type Zone
    top: float = na
    bottom: float = na
    inside: int = 0

fn Zone.touch(self: Zone, price: float)
    if price <= self.top and price >= self.bottom
        self.inside += 1

input length: int = 30, name = "Length", min = 5
let top = tech.highest(high, length)
let bottom = tech.lowest(low, length)
state zone: Zone = Zone()
if bar.index % length == 0
    zone = Zone(top = top, bottom = bottom)
zone.touch(close)
plot(zone.top, name = "Top", color = color.red)
plot(zone.bottom, name = "Bottom", color = color.green)
plot(zone.inside, name = "Closes inside", display = none)

چه چیزی گزارش می‌شود#

در edition 1 سه گروه از اشتباه‌ها خطا هستند.

واژه‌های گزینه. یک گزینه واژه‌ای از یک مجموعهٔ ثابت می‌گیرد: style = line در plot، h_align = left در table.cell. واژه در همان جایی که نوشته شده خوانده می‌شود، چون یک واژه می‌تواند مال چند مجموعه باشد (top هم یک تراز عمودی است و هم جای یک علامت). سه چیز ممکن است اشتباه شود و هر کدام کد خودش را دارد:

  • E3400: نامی تعریف کرده‌اید که واژهٔ همان جا هم هست و نوع دیگری دارد. نام شما برنده است، پس گزینه مقدار شما را می‌گرفت، و موتور به‌جای اینکه برایتان انتخاب کند همین را می‌گوید.
  • E3406: یک واژهٔ تنها که مال چند مجموعه است جدا آمده (let where = top)، پس هیچ چیز نمی‌گوید از کدام مجموعه است.
  • E3407: یک واژهٔ تنها، واژهٔ آن جا نیست. پیام نزدیک‌ترین واژه را نام می‌برد و واژه‌های آن جا را فهرست می‌کند.
Cuprel · خطا E3406
// Mistake: `top` is an option word of more than one set (a vertical alignment and a position), and a bare `let` does not say which one is meant (E3406).
indicator "Ambiguous option word"
    edition = 1
    display = price

let where = top
if bar.is_last
    let t = table.new(top_right, 1, 1)
    table.cell(t, 0, 0, "text", v_align = where)
plot(close)

نوع را بنویسید، و واژه به عنوان واژه‌ای از آن مجموعه خوانده می‌شود:

Cuprel
// The fix for E3406: write the type of the variable, so the word is read as a word of that set.
indicator "Option word with a type"
    edition = 1
    display = price

let where: v_align = top
if bar.is_last
    let t = table.new(top_right, 1, 1)
    table.cell(t, 0, 0, "text", v_align = where)
plot(close)
Cuprel · خطا E3407
// Mistake: `lin` is not a plot style (E3407). The message names the nearest word and lists the words that exist.
indicator "Unknown option word"
    edition = 1
    display = price

plot(close, name = "Close", style = lin)
Cuprel · خطا E3400
// Mistake: a variable named `left` hides the option word `left`, so `h_align = left` reads the number, not the alignment (E3400).
indicator "Variable hides an option word"
    edition = 1
    display = price

let left = 5
if bar.is_last
    let t = table.new(top_right, 1, 1)
    table.cell(t, 0, 0, "text", h_align = left)
plot(close)

رکوردها و enumها. فیلدی که رکورد ندارد در سازنده E3130 است، و عضوی که enum ندارد E3171.

متدها. فراخوانی متدی مثل items.at(i) بر اساس نوع مقدار جلوی آن خوانده می‌شود: at روی آرایه و روی نگاشت (map) یک متد نیست. وقتی نوع معلوم نیست و نام می‌تواند هر کدام باشد، فراخوانی E3170 است و از شما می‌خواهد نوع را بنویسید؛ همین اتفاق می‌افتد وقتی متدی با یک نام را روی دو نوع تعریف کنید و آن را روی پارامتری بدون نوع صدا بزنید.

چه چیزی گزارش نمی‌شود#

این‌ها همه در edition 1 پذیرفته می‌شوند و بدون پیام اجرا می‌شوند. برنامه‌های این صفحه عمداً دربارهٔ آن‌ها ساکت‌اند:

  • مقداری که با نوع نوشته‌شده بعد از نامش جور نیست: let a: int = "hello"، یا متن به‌جای عددی که فیلد یک رکورد می‌خواهد.
  • فراخوانی‌ای که آرگومانش نوع اشتباه دارد، و عملی بین یک متن و یک عدد.
  • فیلدی که رکورد ندارد، وقتی خوانده می‌شود (reading.nothing).
  • یک na جایی که عدد خواسته می‌شود: let x: int = na.

بررسی نوع این‌ها را می‌شمارد، در ابزاری از آزمون‌های خود زبان که روی برنامه‌های پروژه اجرا می‌شود، تا کسانی که زبان را می‌سازند ببینند هر کدام پیش از آنکه پیام شود چقدر پیش می‌آید. اینجا چیزی تصمیم گرفته نشده است: قاعده‌هایی که آن‌ها را گزارش می‌کردند به تعویق افتاده‌اند. یک قاعده فقط وقتی از حالت سایه بیرون می‌آید که شمارشش روی آن برنامه‌ها صفر باشد یا همهٔ موردها بررسی شده باشند. تا آن وقت این صفحه همان فهرست است.

بررسی‌کننده نوع را چطور پیدا می‌کند#

نوع را وقتی می‌داند که اسکریپت آن را بگوید یا همهٔ جاها با هم بخوانند: یک annotation (نوشتن نوع بعد از نام)، یک سازنده یا آرایه‌ای که کامل نوشته شده (array<int>(3, 0)، [1, 2])، فیلد یک رکورد، عضو آرایه‌ای که نوع عضوهایش نوشته شده، و اولین مقدار یک نام همراه با همهٔ مقداردهی‌های بعدی به آن. یک مقداردهی از نوع دیگر، یک مقداردهی ترکیبی، پارامتر تابع بدون نوع، متغیر حلقه: آن وقت نوع نامعلوم است. نوع نامعلوم هرگز خطا نیست و هرگز رفتار اسکریپت را عوض نمی‌کند. اگر می‌خواهید بررسی‌کننده نوعی را بداند که خودش نمی‌تواند پیدا کند، آن را بنویسید.

ببینید هم: مقدارها و نوع‌ها، تابع‌ها، نوع‌ها و enum‌ها، تشخیص‌ها، مثال‌ها: نوع‌ها در حالت سایه.