以下代码无法编译,我不明白为什么不
的原因class FruitProcessor[T <: Fruit] {
def process(fruit: T) = {
// Do something with fruit
}
}
class FruitBlender[T <: Fruit] {
val fruitProcessor = new FruitProcessor[T]
def blend(fruit: T) = {
fruit match {
case b: Banana => fruitProcessor.process(b)
case a: Apple => fruitProcessor.process(a)
}
}
}
sealed trait Fruit
case class Banana(id: String) extends Fruit
case class Apple(id: String) extends Fruit
编译错误符合&#34;找到香蕉,需要T&#34;
我在这里做错了什么?
答案 0 :(得分:3)
process
方法需要类型为T
的参数,但您传递的值为Banana
。编译器不够聪明,无法确定调用T
的代码路径中Banana
总是fruitProcessor.process(b)
。实际上你根本不需要那个匹配表达式。在这种情况下,方法T
中的blend
与T
想要的process
相同。所以你可以拨打fruitProcessor.process(fruit)
。
答案 1 :(得分:1)
说出你的所作所为:
您使用FruitProcessor
的子类T
参数化Fruit
,process
T
。
然后,您使用FoodBlender
的{{1}}子类T
进行参数化,其Fruit
即FoodProcessor[T]
,process
T
process
T
}。
由于您只能[S <: Fruit]
Fruit
而非T
,即只有您的子类型Fruit
Banana
的特定实例,其中参数化参数化使用,而不是所有Apples
,这不适用于特定类型T
和FruitBlender
。 class Pear extends Fruit
上的blend
例如可以是def blend(fruit: Pear)
,在这种情况下,Apple
的签名将是Banana
,当然如果不兼容import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import com.sleepycoat.tapxicon.utils.ScreenUtils;
import java.security.InvalidAlgorithmParameterException;
import static android.view.MotionEvent.ACTION_OUTSIDE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
/**
* Created by egslava on 24/08/16.
* Unfortunately, Android system is not supported (or I could find how) managing keyboard in windows
* (not activities) that are always on top. So we need to manage keyboard manually.
*/
public class TopScreenDrawerLogic {
private static final String TAG = "TopScreenDrawerLogic";
final Keyboarder keyboarder;
// private final View fakeFocus;
View visibleView;
DrawerView drawer;
ScrollerLogic scroller;
private final ScreenUtils utils;
private final WindowManager wm;
public static final int COMMON_WINDOW_FLAGS =
FLAG_LAYOUT_NO_LIMITS | // for fast "resizing". Window can be moved out of screen
FLAG_NOT_TOUCH_MODAL | // other windows (on the background, that our window is not overlapped) can intercept touch events
FLAG_LAYOUT_IN_SCREEN; // need for right positioning (getting into account status bar)
// when FLAG_LAYOUT_IN_SCREEN is set getHeight() will return value - navigation bar height
public static final int BACKGROUND_WINDOW_FLAGS = COMMON_WINDOW_FLAGS |
FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM; // "back" and other hardware buttons will go throw window
public static final int FOREGROUND_WINDOW_FLAGS = COMMON_WINDOW_FLAGS |
// FLAG_LOCAL_FOCUS_MODE |
// FLAG_NOT_TOUCHABLE | // if we want go clicks throw the window
FLAG_WATCH_OUTSIDE_TOUCH; // need to know when user touched outside of window to "unfocus"
private final InputMethodManager imm;
public static WindowManager.LayoutParams createLayout() {
return new WindowManager.LayoutParams(
MATCH_PARENT, MATCH_PARENT, TYPE_PHONE, FOREGROUND_WINDOW_FLAGS, PixelFormat.TRANSLUCENT);
}
//////////////////////////////////////////////////////
// mrtndat add 9/9
//////////////////////////////////////////////////////
public static WindowManager.LayoutParams createLayout(Context context) {
// int w
Point navBarSize = ScreenUtils.getNavigationBarSize(context);
Point screenSize = ScreenUtils.getRealScreenSize(context);
int maxHeight = navBarSize != null ? (screenSize.y - navBarSize.y) :
screenSize.y;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
// params.gravity = Gravity.TOP;
// params.x = 0;
// int diff = 0;
// if (navBarSize != null) {
// diff = maxHeight - navBarSize.y;
// }
// if (navBarSize != null) {
// params.y = -navBarSize.y+144;
// }
return params;
}
//////////////////////////////////////////////////////
// mrtndat end 9/9
//////////////////////////////////////////////////////
public TopScreenDrawerLogic(DrawerView drawer, View visibleView) {
this.visibleView = visibleView;
this.drawer = drawer;
scroller = new ScrollerLogic(drawer);
keyboarder = new Keyboarder(drawer);
utils = new ScreenUtils(drawer.getContext());
wm = drawer.windowManager;
imm = (InputMethodManager) drawer.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
// this.fakeFocus = fakeFocus;
}
public int minY() {
return 0;
}
public int maxY() {
int[] location = new int[2];
visibleView.getLocationInWindow(location);
int visibleViewTop = location[1];
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) visibleView.getLayoutParams();
int visibleViewBottom = visibleViewTop + visibleView.getHeight() + margins.bottomMargin; //just a bit margin;
return utils.getDisplayHeight() - visibleViewBottom;// - navBarHeight;
}
private int minY(int value) {
return Math.max(value, minY());
}
private int maxY(int value) {
return Math.min(maxY(), value);
}
;
public int boundY(int y) {
return maxY(minY(y));
}
// difference between nearest correct Y value and given
public int yCorrection(int y) {
return y - boundY(y);
}
public int shiftDrawer(int dy) {
return shiftDrawer(dy, false);
}
/**
* shifts drawer and returns new y coordinate
*/
public int shiftDrawer(int dy, boolean animated) {
WindowManager.LayoutParams params = drawer.getLayoutParams();
WindowManager wm = drawer.windowManager;
// params.y = params.y + dy;
if (dy > 1500) {
new Throwable().printStackTrace();
}
final int newY = drawer.logic.boundY(params.y + dy);
if (animated) {
new TranslateDrawerAnim(drawer, boundY(drawer.getLayoutParams().y + (int) dy)/* target layout height */, 250).execute();
} else {
params.y = newY;
wm.updateViewLayout(drawer, params);
}
return params.y;
}
public int shiftDrawerByScreenPercent(float dy, boolean animated) {
return shiftDrawer((int) (utils.getDisplayHeight() / 100.0f * dy), animated);
}
public static final int STATE_UNDEFINED = 0;
public static final int STATE_FOREGROUND = 1;
public static final int STATE_BACKGROUND = 2;
public static final int INITIAL_STATE = STATE_FOREGROUND;
public int state = INITIAL_STATE;
public void resetState(View focusedView) {
if (INITIAL_STATE == STATE_BACKGROUND) {
makeBackground();
} else if (INITIAL_STATE == STATE_FOREGROUND) {
makeForeground();
} else throw new RuntimeException(new InvalidAlgorithmParameterException("Strange state"));
}
public void makeBackground() {
new Throwable().printStackTrace();
Log.d(TAG, "makeBackground()" + ", previous state = " + stateToString(state));
if (state == STATE_BACKGROUND) return;
state = STATE_BACKGROUND;
imm.hideSoftInputFromWindow(drawer.getWindowToken(), 0);
WindowManager.LayoutParams params = drawer.getLayoutParams();
WindowManager wm = drawer.windowManager;
params.softInputMode = SOFT_INPUT_STATE_ALWAYS_HIDDEN;
params.flags = BACKGROUND_WINDOW_FLAGS;
wm.updateViewLayout(drawer, params);
// final View focus = drawer.findFocus();
// if (focus != null) focus.postDelayed(new Runnable() {
// @Override
// public void run() {
// imm.hideSoftInputFromWindow(drawer.getWindowToken(), 0, new ResultReceiver(new Handler(new Handler.Callback() {
// @Override
// public boolean handleMessage(Message message) {
// fakeFocus.requestFocus();
// keyboarder.applyPos();
// return true;
// }
// })));
// }
// }, 250);
}
public String stateToString(int state) {
switch (state) {
case STATE_BACKGROUND:
return "background";
case STATE_FOREGROUND:
return "foreground";
default:
throw new RuntimeException("Invalid state");
}
}
public void makeForeground() {
new Throwable().printStackTrace();
Log.d(TAG, "makeForeground()" + ", previous state = " + stateToString(state));
if (state == STATE_FOREGROUND) return;
state = STATE_FOREGROUND;
WindowManager.LayoutParams params = drawer.getLayoutParams();
WindowManager wm = drawer.windowManager;
params.flags = FOREGROUND_WINDOW_FLAGS;
// params.softInputMode = SOFT_INPUT_STATE_UNCHANGED;
params.softInputMode = SOFT_INPUT_STATE_HIDDEN;
// params.softInputMode = SOFT_INPUT_STATE_VISIBLE;
wm.updateViewLayout(drawer, params);
// request focus on focused element. Why? The reason:
// 1. when window is in background state it can't be focused.
// 2. when window is in foreground state some time it focuses last focused element
// 3. when this happens Android shows keyboard but DOESN'T call onFocusChanged
// 4. #Keyboarder class can't process this case correctly and move drawer on keyboard level
// final View focus = drawer.findFocus();
// if (focus != null)focus.postDelayed(new Runnable() {
// @Override
// public void run() {
// focus.requestFocus();
// }
// }, 250);
}
public void dispatchTouchEvent(MotionEvent e) {
Log.d(TAG, "dispatchTouchEvent() called with: " + "e = [" + e + "]");
switch (e.getAction()) {
case ACTION_OUTSIDE:
makeBackground();
break;
default:
makeForeground();
break;
}
}
public boolean delegateOnTouch(MotionEvent e) {
Log.d(TAG, "delegateOnTouch() called with: " + "e = [" + e + "]");
keyboarder.delegateOnTouch(e);
return scroller.delegateOnTouch(e);
}
// need to process keyboard by ourselves
public void delegateOnInputClick(final View v) {
keyboarder.delegateOnInputClick(v);
}
public void delegateOnInputFocus(final View v, final boolean b) {
keyboarder.delegateOnInputFocus(v, b);
}
public boolean delegateOnInterceptTouch(MotionEvent e) {
return scroller.delegateOnInterceptTouch(e);
}
public void callWhenEnterIsPressed() {
}
public void callWhenKeypressed() { // for backpressing
}
public void callWhenKeyboardIsShown() {
}
public void delegateOnKeyPreIme(int keyCode, KeyEvent event) {
keyboarder.delegateOnKeyPreIme(keyCode, event);
}
}
s或<?php
$selvals = array("Manhattan", "Bronx", "Brooklyn");
?>
<label class="checkbox-inline"><input type="checkbox" <?php if(in_array("Manhattan",$selvals)){ echo 'checked="checked"';}?> name="manhattan" value="Manhattan" >Manhattan</label>
<label class="checkbox-inline"><input type="checkbox" <?php if(in_array("Bronx",$selvals)){ echo 'checked="checked"';}?> name="bronx" value="Bronx" >Bronx</label>
<label class="checkbox-inline"><input type="checkbox" <?php if(in_array("Brooklyn",$selvals)){ echo 'checked="checked"';}?> name="brooklyn" value="Brooklyn" >Brooklyn</label>
<label class="checkbox-inline"><input type="checkbox" <?php if(in_array("Queens",$selvals)){ echo 'checked="checked"';}?> name="queen" value="Queens" >Queens</label>
<label class="checkbox-inline"><input type="checkbox" <?php if(in_array("Staten Island",$selvals)){ echo 'checked="checked"';}?> name="staten" value="Staten Island" >Staten Island</label>
s。